Javascript 使用酶的JS单元测试:如何在组件内等待setState';在继续测试用例之前要完成的方法
我有一个组件Javascript 使用酶的JS单元测试:如何在组件内等待setState';在继续测试用例之前要完成的方法,javascript,reactjs,enzyme,Javascript,Reactjs,Enzyme,我有一个组件MyComponent,它具有更新状态的方法doSomething,以及基于这些状态呈现子组件的renderChildren: class MyComponent extends Component { constructor(props) { super(props); ... this.state = { renderChildA: true, renderChildB: false, }; } doSomet
MyComponent
,它具有更新状态的方法doSomething
,以及基于这些状态呈现子组件的renderChildren
:
class MyComponent extends Component {
constructor(props) {
super(props);
...
this.state = {
renderChildA: true,
renderChildB: false,
};
}
doSomething = (params) => {
// Do something...
this.setState({
renderChildA: false,
renderChildB: true,
});
}
renderChildren = () => {
const { renderChildA, renderChildB } = this.state;
if (renderChildA) {
return <ChildComponentA />;
} else if (renderChildB) {
return <ChildComponentB />;
}
}
render() {
return (
<div>
{this.renderChildren()}
...
</div>
);
}
}
但是,上述测试用例失败:
my-component.test.jsx > Some test group name > doSomething should trigger ChildComponentB to pop up
expect(received).toHaveLength(length)
Expected value to have length:
1
Received:
// Some giant JSON object
recevied.length:
0
xxx | const childComponentB = wrapper.find('ChildComponentB');
xxx | expect(childComponentB).toHaveLength(1);
xxx | });
根据日志记录,我看到
doSomething
中的setState
在测试用例中的expect
语句之后被触发。我怀疑这是因为,但我不知道解决方法(除了setTimeout
)。您可以尝试手动更新组件以获取最新状态:
wrapper.instance().doSomething(params); // assume params is defined
wrapper.update();
const childComponentB = container.find('ChildComponentB');
expect(childComponentB).toHaveLength(1);
更多信息:不确定这是否有效,但让我们尝试更新
doSomething
功能
doSomething = (params) => {
this.setState({
renderChildA: false,
renderChildB: true,
},() => this.renderChildren());
}
找到了一个相当简单的解决方案。使用:
test('doSomething应触发ChildComponentB弹出’,async()=>{
常数包装=浅(
,
).潜水();
等待包装器.instane().doSomething(参数);
const childComponentB=wrapper.find('childComponentB');
expect(childComponentB).toHaveLength(1);
});
只需添加async
和wait
test('describe your test', async() => { // add async here
const wrapper = shallow(
<MyComponent
...
/>,
).dive();
await wrapper.instane().doSomething(params); // add wait here
const childComponentB = wrapper.find('ChildComponentB');
expect(childComponentB).toHaveLength(1)
});
test('description your test',async()=>{//add async here
常数包装=浅(
,
).潜水();
wait wrapper.instane().doSomething(params);//在此处添加wait
const childComponentB=wrapper.find('childComponentB');
expect(childComponentB).toHaveLength(1)
});
在测试中,您实际上是在测试是否存在ChildComponentB而不是ChildComponentA const ChildComponentA=container.find('ChildComponentB');是的,我正在检查是否有ChildComponentB
。变量名是一个输入错误。我已经尝试过了,但它会导致与问题中描述的相同的行为。即使使用update()
,在调用expect()
时,状态仍保持不变。
test('doSomething should trigger ChildComponentB to pop up', async() => {
const wrapper = shallow(
<MyComponent
...
/>,
).dive();
await wrapper.instane().doSomething(params);
const childComponentB = wrapper.find('ChildComponentB');
expect(childComponentB).toHaveLength(1);
});
test('describe your test', async() => { // add async here
const wrapper = shallow(
<MyComponent
...
/>,
).dive();
await wrapper.instane().doSomething(params); // add wait here
const childComponentB = wrapper.find('ChildComponentB');
expect(childComponentB).toHaveLength(1)
});
it('check List component for column list', async () => {
#ur code for re-render stuff
await new Promise(resolve => setTimeout(resolve, 0)); // wait for response
# this will sync ur wrapper with latest tree change
wrapper = wrapper.update();
});