为什么这个模拟api不能像预期的那样工作



我正在尝试测试这个简单的api模块:

import fetch from 'isomorphic-fetch';
export const getJson = (endpoint: string) => {
  const options = { credentials: 'include', method: 'GET' };
  return fetch(endpoint, options)
    .then(response => response.json()
      .then(json => {
        if (response.ok) return json;
        return Promise.reject(json.errors);
      })
    )
    .catch(error => {
      if (error.constructor === Array) return error;
      return [error.message];
    });
};

在这个测试中,我模拟fetch:

import { getJson } from '../api';
const mockResponse = (status, statusText, response) => {
  return new window.Response(response, {
    status: status,
    statusText: statusText,
    headers: {
      'Content-type': 'application/json'
    }
  });
};
describe('api middleware', () => {
  describe('getJson', () => {
    it('should return the response on success', () => {
      const expected = { data: ['data'], meta: {} };
      const body = JSON.stringify(expected);
      window.fetch = jest.fn().mockImplementation(() =>
        Promise.resolve(mockResponse(200, null, body)));
      return getJson('http://endpoint').then(actual => expect(actual).toEqual(expected));
    });
  });
});

但是测试失败了:

Expected value to equal:
  {"data": ["data"], "meta": {}}
Received:
  ["Unexpected end of JSON input"]
Difference:
Comparing two different types of values:
  Expected: object
  Received: array

我还没能弄清楚为什么这不起作用。为什么我收到"JSON输入的意外结束"错误?如何在测试中成功地模拟局部fetch ?在这篇中篇文章中,使用的方法基本相同

所以显然测试仍然使用全局取回库,而不是我的补丁版本。解决方案是:

  1. 删除'isomorphic-fetch'模拟(在__mocks__在项目的根)。
  2. 导入'同构取'一次在我的项目的根与import 'isomorphic-fetch;
  3. 删除api模块顶部的"isomorphic-fetch"导入(因为它已经在入口点导入)
  4. 将测试更新为:
测试:

// to make the Response constructor available
import 'isomorphic-fetch';
import { getJson } from '../api';
describe('api middleware', () => {
  describe('getJson', () => {
    beforeEach(() => {
      window.fetch = jest.genMockFunction();
    });
    it('should return the response on success', () => {
      const expected = { data: ['data'], meta: {} };
      const body = JSON.stringify(expected);
      const init = { status: 200, statusText: 'OK' };
      window.fetch.mockReturnValueOnce(Promise.resolve(new Response(body, init)));
      return getJson('http://endpoint').then(actual => expect(actual).toEqual(expected));
    });
  });
});

很可能是因为您的getJson函数不使用全局(窗口)fetch

我建议的方法是使用依赖注入(DI);使getJson检索"http请求"库/函数(在您的示例中为fetch),并在测试中创建一个注入的模拟函数。mock函数将返回您想要作为测试一部分的数据。

相关内容

  • 没有找到相关文章

最新更新