Jest spyOn() 调用实际函数而不是模拟函数

Jest spyOn() calls the actual function instead of the mocked

我正在测试调用辅助函数 callApiapiMiddleware。为了防止调用将发出 API 调用的实际 callApi,我模拟了该函数。但是,它仍然会被调用。

apiMiddleware.js

import axios from 'axios';

export const CALL_API = 'Call API';

export const callApi = (...arg) => {
  return axios(...arg)
    .then( /*handle success*/ )
    .catch( /*handle error*/ );
};

export default store => next => action => {
  // determine whether to execute this middleware
  const callAPI = action[CALL_API];
  if (typeof callAPI === 'undefined') {
    return next(action)
  }

  return callAPI(...callAPI)
    .then( /*handle success*/ )
    .catch( /*handle error*/ );
}

apiMiddleware.spec.js

import * as apiMiddleware from './apiMiddleware';

const { CALL_API, default: middleware, callApi } = apiMiddleware;

describe('Api Middleware', () => {

  const store = {getState: jest.fn()};
  const next = jest.fn();
  let action;

  beforeEach(() => {
    // clear the result of the previous calls
    next.mockClear();
    // action that trigger apiMiddleware
    action = {
      [CALL_API]: {
        // list of properties that change from test to test 
      }
    };
  });

  it('calls mocked version of `callApi', () => {
    const callApi = jest.spyOn(apiMiddleware, 'callApi').mockReturnValue(Promise.resolve());

    // error point: middleware() calls the actual `callApi()` 
    middleware(store)(next)(action);

    // assertion
  });
});

请忽略 callApi 函数的操作属性和参数。我不认为他们是我要表达的重点。

如果您需要进一步说明,请告诉我。

开玩笑的 mocking 只适用于导入的函数。在您的 apiMiddleware.js 中,default 函数正在调用 callApi 变量,而不是 "exported" callApi 函数。要使模拟工作,请将 callApi 移动到它自己的模块中,并将其 import 移动到 apiMiddleware.js

问得好!

我解决了将我的代码转换为 Class 的问题,示例:

// Implementation 
export class Location {
  getLocation() {
    const environment = this.getEnvironmentVariable();
    return environment === "1" ? "USA" : "GLOBAL";
  }
  getEnvironmentVariable() {
    return process.env.REACT_APP_LOCATION;
  }
}


// Test
import { Location } from "./config";

test('location', () => {
  const config = new Location();
  jest.spyOn(config, "getEnvironmentVariable").mockReturnValue("1")

  const location = config.getLocation();
  expect(location).toBe("USA");
});