我正在为一个React应用程序编写一个集成测试,即一个将多个组件一起测试的测试,并且我想模拟对外部服务的任何调用。
问题是测试似乎在执行异步回调之前执行,导致我的测试失败。
有没有办法解决?我可以以某种方式等待调用异步代码完成吗?
这是一些错误的伪代码来说明我的观点。
我想测试一下,当我挂载Parent时,其Child组件将呈现从外部服务返回的内容,我将对此进行模拟。
class Parent extends component
{
render ()
{
<div>
<Child />
</div>
}
}
class Child extends component
{
DoStuff()
{
aThingThatReturnsAPromise().then((result) => {
Store.Result = result
})
}
render()
{
DoStuff()
return(<div>{Store.Result}</div>)
}
}
function aThingThatReturnsAPromise()
{
return new Promise(resolve =>{
eternalService.doSomething(function callback(result) {
resolve(result)
}
}
}
当我在测试中执行此操作时,它会失败,因为它在触发回调之前已执行。
jest.mock('eternalService', () => {
return jest.fn(() => {
return { doSomething: jest.fn((cb) => cb('fakeReturnValue');
});
});
describe('When rendering Parent', () => {
var parent;
beforeAll(() => {
parent = mount(<Parent />)
});
it('should display Child with response of the service', () => {
expect(parent.html()).toMatch('fakeReturnValue')
});
});
我该如何测试?我知道angular使用zonejs解决了这个问题,React中是否有等效的方法?
这是一个片段,等待解决待处理的Promises:
const flushPromises = () => new Promise(setImmediate);
请注意,setImmediate是非标准功能(并且不应成为标准功能)。但是,如果足以满足您的测试环境,则应该是一个很好的解决方案。其说明:
此方法用于中断长时间运行的操作并在浏览器完成其他操作(例如事件和显示更新)后立即运行回调函数。
以下是使用async / await大致使用它的方法:
it('is an example using flushPromises', async () => {
const wrapper = mount(<App/>);
await flushPromises();
wrapper.update(); // In my experience, Enzyme didn't always facilitate component updates based on state changes resulting from Promises -- hence this forced re-render
// make assertions
});
如果您想要一些实际的示例,我在这个项目中经常使用。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句