防止私有组件

时间:2016-12-06 17:13:39

标签: reactjs enzyme

如何使用酶防止私有组件上的浅呈现?

这是一个组件示例:

// 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);
  });
});

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

4 个答案:

答案 0 :(得分:1)

  

浅层渲染有助于限制自己测试a   组件作为一个单元,并确保您的测试不是间接的   主张儿童组件的行为

我认为你正试图做那些浅薄的试图避免^^。

您可以直接对私有组件进行单元测试或使用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

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

答案 1 :(得分:1)

在这种情况下(通常)你的私有组件只是一个函数,在公共组件的渲染中使用它作为函数,你将能够用浅包装器测试它的渲染。

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

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

答案 2 :(得分:1)

您必须导出私有组件

export const FooSubtitle = ...

现在,您可以使用其所有道具变体对其进行测试。

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

答案 3 :(得分:0)

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

  1. 至少有酶v2.5
  2. 查看Enzyme .dive() API:浅呈现当前包装器的非DOM子项
  3. 这是一个有效的例子:

    // 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);
      });
    });