【发布时间】:2019-12-06 03:21:24
【问题描述】:
我目前正忙于编写我的 React-App 测试。
我的 componentDidMount 方法中有一个异步调用,并在返回后更新状态。但是,我没有得到这个工作。
我找到了几种解决方案,但似乎都没有按预期工作。下面是我到过的最近的点。
应用:
class App extends Component<{}, IState> {
state: IState = {
fetchedData: false
};
async componentDidMount() {
await thing.initialize();
this.test();
}
test = () => {
this.setState({ fetchedData: true })
};
render() {
return this.state.fetchedData ? (
<div>Hello</div>
) : (
<Spinner />
);
}
}
测试
it('Base test for app', async () => {
const spy = spyOn(thing, 'initialize').and.callThrough(); // just for debugging
const wrapper = await mount(<App />);
// await wrapper.instance().componentDidMount(); // With this it works, but componentDidMount is called twice.
wrapper.update();
expect(wrapper.find('Spinner').length).toBe(0);
});
嗯,所以...thing.initialize 被调用(它是一个获取一些东西的异步方法)。 如果我明确调用 wrapper.instance().componentDidMount() 那么它将起作用,但 componentDidMount 将被调用两次。
这是我尝试过但没有成功的想法:
- 监视 thing.initialize() -> 在方法被调用并完成之后,我没有发现我是如何进行测试的。。
- 监视 App.test -> 此处相同
- 使用承诺而不是异步等待
- 一开始,我的componentDidMount中有一个thing.initialize().then(this.test)
不会太多,但有人能告诉我我缺少哪一部分吗?
【问题讨论】:
-
您真的需要保留
thing.initialize()才能成为真正的电话吗?对我来说,测试的代码看起来不错(实际上你不需要wrapper.update()),但它只有在thing.initialize()立即解决/拒绝时才会起作用。如果这是一个非零延迟的真正调用,那么您的测试在响应到来之前就完成了。 -
是的,在调用 app.test 之前进行测试,这正是问题所在。 Thing.initialize 是一个异步函数,它获取一些数据并将其存储在本地存储中。因此它不会(我认为不能)立即返回。
-
是单元测试还是集成测试?
-
我想测试初始化后呈现的应用页面。作为替代方案,我可以创建一个在初始化后呈现的内容的组件,并在显式调用 thing.initialize 后对其进行测试。但我认为这将是一种应该以某种方式工作的解决方法。
标签: reactjs async-await jestjs