【问题标题】:How do I mock a specific function from a module for a specific test (Jest)如何从模块中模拟特定功能以进行特定测试(Jest)
【发布时间】:2018-07-31 01:59:40
【问题描述】:

我有一个 api.js 文件,其中包含我的 api 调用。它看起来像这样:

// api.js

// reusable fetch call
export const makeFetch = async (url, options) => {
  try {
    const response = await fetch(url, options);

    if (!response.ok) {
      throw new Error(`${response.status}`);
    }

    return await response.json();
  } catch (error) {
    throw new Error(`Network request failed. (error: ${error.message})`);
  }
};

// actual fetch call
export const getCards = async () => {
  const url = 'http://localhost:3001/api/v1/cards';
  return await makeFetch(url);
};

然后我有一个 api.test.js 文件,如下所示:

//api.test.js

import { makeFetch, getCards } from './api';

describe('makeFetch', () => {

  // three successful tests

});

// this is where I have issues

describe('getCards', () => {
  it('calls makeFetch', async () => {

    await getCards();

    expect(makeFetch).toHaveBeenCalledTimes(1);
  });
});

这是我得到的错误:

FAIL  src\api\api.test.js
  ● getCards › calls makeFetch

    ReferenceError: makeFetch is not defined

      at Object.it.only (src/api/api.test.js:51:15)
          at new Promise (<anonymous>)
      at Promise.resolve.then.el (node_modules/p-map/index.js:46:16)
          at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:182:7)

有谁知道如何通过使我以前的测试失败来通过此测试?感谢您的宝贵时间。

【问题讨论】:

    标签: testing jestjs


    【解决方案1】:

    您需要创建一个 makeFetch 的模拟。您可以使用spyOnmockReturnValue 来做到这一点。

    您需要将 makeFetch 移动到它自己的文件 (lib.js) 中,以便您可以在测试中模拟和替换它:

    // ---- lib.js ----
    // reusable fetch call
    export const makeFetch = async (url, options) => {
      try {
        const response = await fetch(url, options);
    
        if (!response.ok) {
          throw new Error(`${response.status}`);
        }
    
        return await response.json();
      } catch (error) {
        throw new Error(`Network request failed. (error: ${error.message})`);
      }
    };
    
    
    
    // ---- api.js ----
    import { makeFetch } from './lib';
    
    // actual fetch call
    export const getCards = async () => {
      const url = 'http://localhost:3001/api/v1/cards';
      return await makeFetch(url);
    };
    
    
    
    // ---- api.test.js ----
    import * as lib from './lib';
    import { getCards } from './api';
    
    describe('makeFetch', () => {
    
      // three successful tests
    
    });
    
    describe('getCards', () => {
      it('calls makeFetch', async () => {
        const simulatedResponse = { data: 'simulated response' };
    
        // mock makeFetch
        const mock = jest.spyOn(lib, 'makeFetch');
        mock.mockReturnValue(Promise.resolve(simulatedResponse));
    
        const result = await getCards();
    
        expect(result).toEqual(simulatedResponse);
        expect(mock).toHaveBeenCalledTimes(1);
        expect(mock).toHaveBeenCalledWith('http://localhost:3001/api/v1/cards');
    
        // restore makeFetch
        mock.mockRestore();
      });
    });
    

    【讨论】:

    • 感谢您的回复,但是在运行此程序时,由于:“TypeError: mock.mockResolvedValue is not a function”如果我将该行更改为:“mock.mockImplementationOnce(() = > Promise.resolve(simulatedResponse));"测试响应变为:期望值等于:{"data": "simulated response"} Received: [[Object], [Object], ...]
    • 啊,你使用的是早期版本的 Jest,我会在一分钟内更新我的答案
    • 行得通!你是最棒的。我正在使用 create-react-app 所以我猜包含的 jest 版本是旧的。非常感谢您的帮助
    • 很高兴,很高兴它有帮助
    • 哎呀,谢谢。完毕。 (我投了赞成票,但它不会显示,因为我的声望
    猜你喜欢
    • 2018-07-29
    • 1970-01-01
    • 2019-08-03
    • 1970-01-01
    • 2022-01-05
    • 1970-01-01
    • 2019-07-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多