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

NER*_*ARD 2 javascript mocking jestjs redux-middleware

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

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*/ );
}
Run Code Online (Sandbox Code Playgroud)

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
  });
});
Run Code Online (Sandbox Code Playgroud)

请忽略操作的属性和函数参数callApi。我不认为他们是我试图表达的观点的关注点。

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

Her*_*kov 5

开玩笑的嘲讽只适用于导入的函数。在您apiMiddleware.jsdefault函数中调用callApi变量,而不是“导出”callApi函数。为了使模拟工作,callApi进入它自己的模块,并importapiMiddleware.js

好问题!