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

时间:2016-10-07 14:58:50

标签: reactjs asynchronous promise jestjs fetch-api

我的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中模拟错误然后测试它。有谁知道我会如何嘲笑最后一个断言?

2 个答案:

答案 0 :(得分:3)

通过查看jest-fetch-mock的实施情况,它始终会解除承诺,这意味着您的fetch永远不会转到catch。所以你需要一个Promise.reject(),在测试中你需要做一些像 -

这样的事情
it('handles fetch errors', () => {
  return get('doesnotexist')
    .catch(error => expect(error).toEqual('some error'));
});

答案 1 :(得分:0)

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

fetch.mockResponseOnce(null, init);