测试渲染道具组件

时间:2018-09-20 08:31:16

标签: reactjs enzyme

如果我有这样的渲染道具组件:

export class ParentComponent extends React.Component {
    render() {
        <Loader loading={false}>
                {() =>
                    <SomeChildComponent />
               }
    }
}

如何进行单元测试?

test('should output child component',  => {
    const wrapper = shallow(<ParentComponent />);
    expect(wrapper.find(SomeChildComponent).length).to.be(1);
}

失败-如果我改为测试Loader组件-测试通过:

  expect(wrapper.find(Loader).length).to.be(1);

如何测试输出SomeChildComponent?

2 个答案:

答案 0 :(得分:2)

您的内部函数() =><SomeChildComponent />从未执行过,因此您的测试表明SomeChildComponent不存在的事实。您只需要调用它(注意额外的括号)即可:

export class ParentComponent extends React.Component {
    render() {
        return (<Loader loading={false}>
            { (() =><SomeChildComponent />)()}
        </Loader>);
    }
}

我们可以将其重构为更多的render-props方式:

export class ParentComponent extends React.Component {
    render() {
        return (<Loader loading={false}>
            { this.props.render()}
        </Loader>);
    }
}

然后相应地更改测试:

const render = () => <SomeChildComponent />;
const wrapper = shallow(
    <ParentComponent render={render} />
);

但是,此测试实际上不是一项unit测试,因为它一次只能测试一个以上的组件。要摆脱这种依赖关系,我们可以检查是否调用了render()

const renderMock = jest.fn();
const wrapper = shallow(<ParentComponent render={ renderMock } />);
expect(wrapper.find('Loader').exists()).toBeTruthy();
expect(renderMock).toHaveBeenCalled();

如果您的render()接受了一些参数,则可以考虑使用.toHaveBeenCalledWith

答案 1 :(得分:0)

如果您使用的是Enzyme 3.8.0或更高版本,则可以遵循此指南:

https://medium.com/@fran.villar.rosa/how-to-test-renderprops-with-enzyme-3-8-0-c079622f68ca

在您的示例中:

export class ParentComponent extends React.Component {
    render() {
        <Loader loading={false}>
                {() =>
                    <SomeChildComponent />
               }
    }
}


const wrapper = shallow(<ParentComponent />)
  .find(Loader)
  .renderProp('children')({yourPropsHere: 'example'});

expect(wrapper).toMatchSnapshot()

您必须在测试文件中导入Loader组件。