【问题标题】:Jest Unit test, mock implementation of IF condition within function for complete code coverageJest 单元测试,在函数内模拟实现 IF 条件以实现完整的代码覆盖
【发布时间】:2018-11-05 20:49:25
【问题描述】:

我在一个文件中有一个 API 脚本

const ApiCall = {
  fetchData: async (url) => {
    const result = await fetch(url);
    if (!result.ok) {
      const body = await result.text(); // uncovered line
      throw new Error(`Error fetching ${url}: ${result.status}  ${result.statusText} - ${body}`); // uncovered line
    }
    return result.json();
  },
};

export default ApiCall;

当我模拟调用时,代码覆盖率中有两行未被发现。

知道如何让它们也覆盖。

这是我迄今为止尝试过的,但不起作用

  it('test', async () => {   
    ApiCall.fetchData = jest.fn();
    ApiCall.fetchData.result = { ok: false };
  });

我是 Jest 的新手,所以任何帮助都会很棒。

【问题讨论】:

    标签: javascript reactjs jestjs enzyme


    【解决方案1】:

    您需要在测试规范中提供一个存根响应,以便触发 if 语句。 https://www.npmjs.com/package/jest-fetch-mock 将允许您这样做。他们 npm 页面上的示例应该为您提供所需的 https://www.npmjs.com/package/jest-fetch-mock#example-1---mocking-all-fetches

    基本上,结果存储在 state(redux) 中并从那里调用。 jest-fetch-mock 覆盖您的 api 调用/路由,并在框架内返回存储在 redux 中的结果。

    【讨论】:

      【解决方案2】:

      假设您要测试的是 ApiCall,那么您需要模拟 fetch。您正在模拟整个 ApiCall,因此这些行将永远不会执行。

      另外,你有一个问题,因为如果你发现错误或承诺拒绝,json() 将不可用,因此该行将触发错误。

      试试这个(没有测试过):

      it('test error', (done) => {  
      let promise = Promise.reject(new Error("test"));
      global.fetch = jest.fn(() => promise); //You might need to store the original fetch before swapping this
          ApiCall.fetchData()
      .catch(err => );
         expect(err.message).toEqual("test");
         done();
        });
      
      it('test OK', (done) => {  
      let promise = Promise.resolve({
         json: jest.fn(() => {data: "data"})
      });
      global.fetch = jest.fn(() => promise); 
          ApiCall.fetchData()
      .then(response => );
         expect(response.data).toEqual("data");
         done();
        });
      

      这可能不会立即奏效,但希望您能明白这一点。在这种情况下,您已经在使用 Promise,因此请参阅我在测试中添加了 done() 回调,因此您可以告诉 jest 您已完成处理。还有另一种方法可以让 jest 等待承诺,例如“return promise.then()”。

      请回帖

      【讨论】:

      • 不错的解决方法。我假设 fetch = jest.fn(() => promise) 是一样的
      • 嗯其实我错了。我认为fetch 就像 Axios,来自进口。现在我看到它在浏览器中是本机的。所以我的建议可能行不通。
      猜你喜欢
      • 1970-01-01
      • 2020-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-25
      相关资源
      最近更新 更多