我正在尝试使用jest来测试我的componentDidMount方法:
componentDidMount() {
agent.Gatherings.getAll().then((result) => {
this.setState({ gatherings: result }) //no code coverage
}).catch((err) => {
this.setState({ gatherings: [] }) //no code coverage
})
}
然而,我的其他测试之一工作正常:
it('test gathering List is rendered', () => {
wrapper.setState({ gatherings: [TestGathering] })
expect(wrapper.find('MyList').length).toEqual(1);
});
我希望在我的测试中涵盖每一行。如何让我的组件DidMount()中的行都开玩笑地进行测试?
更新,我正在将文件直接导入测试文件。我正在导入的文件称为代理.js。在缺少行的函数中调用的代码是:
agent.js
export const requests = {
get: url => fetch(url).then(res => res.json()),
post: (url, body) =>
fetch(url, {
method: 'POST',
body: body,
headers: {
'Content-Type': 'application/json'
}
}).then(res => res.json()) //also this line lacks coverage
}
export const Gatherings = {
getAll: () =>
requests.get(API_ROOT + '/gatherings')
}
export default {
Gatherings
}
问题
在测试运行时,必须运行一行代码才能包含在Jest
代码覆盖率中。
详
没有覆盖的两行是agent.Gatherings.getAll
返回的Promise
的回调。
Promise
回调将添加到 PromiseJobs 队列中,并在当前消息完成后和下一条消息运行之前运行。
这就是为什么这些行目前不包括在代码覆盖率中的原因......现在,它们在同步测试完成之前不会运行。
溶液
您只需要确保这两行在测试运行时运行。
详
理想的方法是直接在测试中await
Promise
。
在这种情况下,Promise
不容易从测试中访问,因此需要不同的方法。
解决方法
如果agent.Gatherings.getAll
被模拟为立即解析或拒绝,则在组件完成渲染时,Promise
回调将在 PromiseJobs 中排队。
要让Promise
回调运行,请使用async
测试函数并调用await Promise.resolve();
该函数实质上是在 PromiseJobs 结束时对测试的其余部分进行排队,并让任何挂起的作业首先运行:
import * as React from 'react';
import { shallow } from 'enzyme';
import { Comp } from './code'; // <= import your component here
import * as agent from './agent';
describe('Component', () => {
let spy;
beforeEach(() => {
spy = jest.spyOn(agent.Gatherings, 'getAll');
})
afterEach(() => {
spy.mockRestore();
})
it('updates when agent.Gatherings.getAll() resolves', async () => { // use an async test function
const response = [ 'gathering 1', 'gathering 2', 'gathering 3' ];
spy.mockResolvedValue(response);
const wrapper = shallow(<Comp />); // render your component
await Promise.resolve(); // let the callback queued in PromiseJobs run
expect(wrapper.state()).toEqual({ gatherings: response }); // SUCCESS
});
it('handles when agent.Gatherings.getAll() rejects', async () => { // use an async test function
spy.mockRejectedValue(new Error());
const wrapper = shallow(<Comp />); // render your component
await Promise.resolve(); // let the callback queued in PromiseJobs run
expect(wrapper.state()).toEqual({ gatherings: [] }); // SUCCESS
});
});
现在,您应该对componentDidMount
中的Promise
回调具有代码覆盖率。