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