问题描述
我正在尝试为需要在其 componentWillMount
方法中完成异步操作的 React 组件编写测试.componentWillMount
调用一个函数,作为一个 prop 传递,它返回一个 promise,我在我的测试中模拟了这个函数.
I'm trying to write a test for a React component that needs to complete an asynchronous action in its componentWillMount
method. componentWillMount
calls a function, passed as a prop, which returns a promise, and I mock this function in my test.
这工作正常,但如果测试在调用 setImmediate
或 process.nextTick
时失败,异常不会由 Jest 处理,它会过早退出.在下面,您可以看到我什至尝试捕获此异常,但无济于事.
This works fine, but if a test fails in a call to setImmediate
or process.nextTick
, the exception isn't handled by Jest and it exits prematurely. Below, you can see I even try to catch this exception, to no avail.
如何在 Jest 中使用 setImmediate
或 nextTick
之类的东西?这个问题的公认答案是我试图实施但未成功的答案:React Enzyme - Test`componentDidMount` 异步调用.
How can I use something like setImmediate
or nextTick
with Jest? The accepted answer to this question is what I'm trying to implement unsuccessfully: React Enzyme - Test `componentDidMount` Async Call.
it('should render with container class after getting payload', (done) => {
let resolveGetPayload;
let getPayload = function() {
return new Promise(function (resolve, reject) {
resolveGetPayload = resolve;
});
}
const enzymeWrapper = mount(<MyComponent getPayload={getPayload} />);
resolveGetPayload({
fullname: 'Alex Paterson'
});
try {
// setImmediate(() => {
process.nextTick(() => {
expect(enzymeWrapper.hasClass('container')).not.toBe(true); // Should and does fail
done();
});
} catch (e) {
console.log(e); // Never makes it here
done(e);
}
});
Jest v18.1.0
Jest v18.1.0
节点 v6.9.1
推荐答案
另一个可能更简洁的解决方案,使用 async/await 并利用 jest/mocha 的能力来检测返回的承诺:
Another potentially cleaner solution, using async/await and leveraging the ability of jest/mocha to detect a returned promise:
// async test utility function
function currentEventLoopEnd() {
return new Promise(resolve => setImmediate(resolve));
}
it('should render with container class after getting payload', async () => {
// mock the API call in a controllable way,
// starts out unresolved
let resolveGetPayload; // <- call this to resolve the API call
let getPayload = function() {
return new Promise(function (resolve, reject) {
resolveGetPayload = resolve;
});
}
// instanciate the component under state with the mock
const enzymeWrapper = mount(<MyComponent getPayload={getPayload} />);
expect(enzymeWrapper.hasClass('container')).not.toBe(true);
resolveGetPayload({
fullname: 'Alex Paterson'
});
await currentEventLoopEnd(); // <-- clean and clear !
expect(enzymeWrapper.hasClass('container')).toBe(true);
});
这篇关于Jest:测试不能在 setImmediate 或 process.nextTick 回调中失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!