当我在react上对此componentDidMount运行测试时,显然没有涵盖几行?

时间:2019-02-27 03:49:14

标签: reactjs unit-testing react-native jestjs

我正在尝试使用笑话来测试我的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);
  });

我希望测试中涵盖所有内容。我如何才能开玩笑地对我的componentDidMount()中的行进行全部测试?

更新,我正在将文件直接导入测试文件。我要导入的文件称为agent.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
}

1 个答案:

答案 0 :(得分:2)

问题

在运行测试的同时,必须运行一行代码,以使其包含在Jest代码覆盖率中。


详细信息

没有覆盖的两行是Promise返回的agent.Gatherings.getAll的回调。

Promise回调被添加到PromiseJobs queue中,并在当前消息完成之后和下一条消息运行之前运行

这就是为什么这些行当前未包含在代码覆盖范围之内的原因。现在它们直到同步测试完成后才运行。


解决方案

您只需要确保测试运行时这两行就可以运行。


详细信息

理想的方法是await the Promise directly in your test

在这种情况下,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
  });
});

您现在应该在Promise中的componentDidMount回调上有代码覆盖。