如何用 jest 测试此 api 中间件是不是处理 fetch 引发的错误?

Posted

技术标签:

【中文标题】如何用 jest 测试此 api 中间件是不是处理 fetch 引发的错误?【英文标题】:How do I test with jest whether this api middleware handles errors thrown by fetch?如何用 jest 测试此 api 中间件是否处理 fetch 引发的错误? 【发布时间】:2017-02-16 15:10:26 【问题描述】:

我的 react/redux 应用程序中有以下 api 中间件,我正在用 jest 进行单元测试。模块代码为:

// ./src/middleware/api.js

import fetch from 'isomorphic-fetch';

// Checks if the returned statuscode is in the successful range
const handleErrors = (response) => 
  if (!response.ok) 
    throw Error(response.statusText);
  
  return response;
;

export const get = (endpoint) => 
  const options =  credentials: 'include', method: 'GET' ;

  return fetch(endpoint, options)
    .then(handleErrors)
    .then(response => response.json())
    .catch(error => error.message);
;

测试是:

// ./src/middleware/__tests__/api.test.js

import fetch from 'isomorphic-fetch';
import  get  from '../api';

// Mock calls to fetch by the api middleware
// loads https://github.com/jefflau/jest-fetch-mock instead of fetch
jest.mock('isomorphic-fetch');

describe('api middleware', () => 
  describe('get', () => 
    it('should return the response on success', () => 
      const expected =  data: ['data'], meta:  ;
      const body = JSON.stringify(expected);
      const init =  status: 200, statusText: 'OK' ;

      fetch.mockResponseOnce(body, init);

      return get('http://endpoint').then(actual => expect(actual).toEqual(expected));
    );

    it('should return the statusText for unsuccessful status codes', () => 
      const expected = 'Unauthorized';
      const body = JSON.stringify( errors: ['You are not logged in'] );
      const init =  status: 401, statusText: expected ;

      fetch.mockResponseOnce(body, init);

      return get('http://endpoint').then(actual => expect(actual).toEqual(expected));
    );

    // I have not been able to mock this so far    
    it('handles fetch errors', () => 
      return get('doesnotexist').then(actual => expect(actual).toEqual(false));
    );
  );
);

在最后一个断言中,我想测试它是否捕获了 fetch 引发的错误(例如,当没有网络连接时)。但我在测试时遇到了麻烦。我不确定如何在 fetch 中模拟错误然后对其进行测试。有谁知道我将如何嘲笑最后一个断言?

【问题讨论】:

【参考方案1】:

通过查看jest-fetch-mock 的实现,它总是会解决promise,这意味着您的fetch 永远不会转到catch。所以你需要有一个Promise.reject() 并且在你的测试中你需要做一些类似的事情 -

it('handles fetch errors', () => 
  return get('doesnotexist')
    .catch(error => expect(error).toEqual('some error'));
);

【讨论】:

【参考方案2】:

如果你给它一个无效的身体,它会绊倒你的承诺的捕获部分。

fetch.mockResponseOnce(null, init);

【讨论】:

以上是关于如何用 jest 测试此 api 中间件是不是处理 fetch 引发的错误?的主要内容,如果未能解决你的问题,请参考以下文章

如何用 Jest 单元测试覆盖 TypeORM @Column 装饰器?

如何用 jest 测试 redux saga?

如何用 Jest 正确实现这样的测试套件架构?

如何用 Jest 测试一系列数字?

如何用 jest 测试 nuxt?

如何用 jest 在服务 (NestJS) 中测试模型 (Mongoose)