假设我有一个Component,它呈现一个简单的div,其中包含一个从0开始并每秒加1的整数。因此,在5秒后,组件应该呈现" 5" 30秒后,它应该呈现" 30"等等。如果我想测试这个组件并确保它在5秒后呈现它应该是什么,我可能会写这样的东西。
it('should render <5> after 5 seconds', () => {
const time = mount(<Timer/>)
setTimeout(() => {
expect(time.text()).toEqual('5')
}, 5000)
})
然而,这并不起作用,因为测试从未实际运行期望并且无论如何都返回通过。即使它确实有效,使用这样的超时也会非常低效,因为测试必须等待5秒。如果我想模拟更长的时间怎么办?在做了一些搜索之后,我发现jest实际上有一个timer mock,但我似乎无法弄清楚如何在这种情况下实现它。任何帮助将不胜感激。谢谢!
答案 0 :(得分:1)
为了让Jest知道你的测试是异步的,你需要:1)返回一个Promise,或者2)在测试回调中声明一个参数,如下所示:
it('should render <5> after 5 seconds', done => {
// test stuff
});
来源:https://facebook.github.io/jest/docs/en/asynchronous.html
让测试工作:
it('should render <5> after 5 seconds', done => {
jest.useFakeTimers(); // this must be called before any async things happen
const time = mount(<Timer/>);
setTimeout(() => {
// Note the placement of this try/catch is important.
// You'd think it could be placed most anywhere, but nope...
try {
// If this assertion fails, an err is thrown.
// If we do not catch()...done.fail(e) it,
// then this test will take jasmine.DEFAULT_TIMEOUT_INTERVAL (5s unless you override)
// and then fail with an unhelpful message.
expect(time.text()).toEqual('5');
done();
} catch(e) {
done.fail(e);
}
}, 5000);
jest.runTimersToTime(5000); // This basically fast forwards 5s.
});
答案 1 :(得分:0)
你必须在'require'你的组件之前调用jest.useFakeTimers();
来模拟setTimeout。
这里我们通过调用jest.useFakeTimers();来启用伪计时器。这个 使用模拟函数模拟setTimeout和其他计时器函数。
要测试异步工作流程Jest documentation says,您必须为每个'it'函数回调返回Promise。
要测试异步函数,只需从中返回一个promise。什么时候 运行测试,Jest将等待承诺解决之前 让测试完成。您也可以从中返回承诺 beforeEach,afterEach,beforeAll或afterAll functions。例如, 假设fetchBeverageList()返回应该承诺的promise 解析为其中包含柠檬的列表。你可以用以下方法测试:
所以你可以这样写:
it('should render <5> after 5 seconds', () => {
jest.useFakeTimers();
//only after that, require your componenet
let Timer = require('./timer');
const time = mount(<Timer/>);
jest.runAllTimers();
expect(setTimeout.mock.calls.length).toBe(1);
expect(setTimeout.mock.calls[0][1]).toBe(5000);
expect(time.text()).toEqual('5');
})