防止私有组件上的酶浅渲染

Prevent enzyme shallow rendering on private component

如何防止使用酶对私有组件进行浅渲染?

这是一个组件示例:

// foo.jsx 
import React from 'react';

// Private component
const FooSubtitle = ({subtitle}) => {
  if (!subtitle) return null;

  return <div className="foo__subtitle">{subtitle}</div>;
};

// Public component
const Foo = ({title, subtitle}) => (
  <div className="foo">
    <div className="foo__title">{title}</div>
    <FooSubtitle subtitle={subtitle} />
  </div>
);

export default Foo;

这是我的规格:

// foo.spec.js
import React from 'react';
import {shallow} from 'enzyme';
import Foo from './foo.jsx';

describe('Foo', () => {

  it('should render a subtitle', () => {
    const wrapper = shallow(<Foo title="my title" subtitle="my subtitle" />);

    // This test doesn't work, so I cannot test the render of my component
    expect(wrapper.find('.foo__subtitle').length).toBe(1);

    // This one works, but it is not relevant
    expect(wrapper.find('FooSubtitle').length).toBe(1);
  });
});

有什么想法吗? 非常感谢。

Shallow rendering is useful to constrain yourself to testing a component as a unit, and to ensure that your tests aren't indirectly asserting on behavior of child components.

我认为你正在尝试做 shallow 试图避免的事情 ^^。

您可以直接对私有组件进行单元测试,也可以使用 render :

expect(wrapper.find(Foo).render().find('.foo__subtitle')).to.have.length(1);

如此处解释:https://github.com/airbnb/enzyme/blob/master/docs/api/ShallowWrapper/render.md

但是在这两种情况下,您都需要导出您的组件,我必须承认我在使用您的组件进行测试时遇到了错误。 :/

在这种情况下(通常情况下)您的私有组件只是一个函数,将其用作 public 组件渲染中的函数,您将能够使用浅层包装器测试其渲染.

<div className="foo">
  <div className="foo__title">{title}</div>
  {FooSubtitle({subtitle})}
</div>

否则,我不确定拥有复杂的私有组件是不是个好主意...

如果您有私有组件,并且想要测试它们的实现,您应该:

  1. 酶至少 v2.5
  2. 查看 Enzyme .dive() API:浅渲染当前包装器的非 DOM 子级

这是一个工作示例:

// foo.jsx
import React from 'react';

// Private component
const FooSubtitle = ({subtitle}) => {
  if (!subtitle) return null;

  return <div className="foo__subtitle">{subtitle}</div>;
};

// Public component
const Foo = ({title, subtitle}) => (
  <div className="foo">
    <div className="foo__title">{title}</div>
    <FooSubtitle subtitle={subtitle} />
  </div>
);

export default Foo;

// foo.spec.js
import React from 'react';
import {shallow} from 'enzyme';
import Foo from './foo.jsx';

describe('Foo', () => {

  it('should render a subtitle', () => {
    const wrapper = shallow(<Foo title="my title" subtitle="my subtitle" />);

    // This test works, but it is not relevant
    expect(wrapper.find('FooSubtitle').length).toBe(1);

    // This one need the `dive()` API to work
    expect(wrapper.find('FooSubtitle').dive().find('.foo__subtitle').length).toBe(1);
  });
});

您必须导出您的私有组件,

export const FooSubtitle = ...

现在,您可以单独测试它及其所有道具变体。

然后您可以像往常一样在 Foo 组件的渲染中使用特定道具测试 FooSubtitle 的存在,仅此而已。