如何在开玩笑中模拟 api 调用以进行 saga 测试

How to mock the api call in jest for saga test

我正在编写测试来测试我的传奇。谁能指导我如何更改下面的代码以便我可以模拟 api 调用?我不想测试真实数据。

import { call, put } from 'redux-saga/effects';

import { API_BUTTON_CLICK_SUCCESS, } from './actions/consts';
import { getDataFromAPI } from './api';

it('apiSideEffect - fetches data from API and dispatches a success action', () => {
  const generator = apiSideEffect();

  expect(generator.next().value)
    .toEqual(call(getDataFromAPI));

  expect(generator.next().value)
    .toEqual(put({ type: API_BUTTON_CLICK_SUCCESS }));

  expect(generator.next())
    .toEqual({ done: true, value: undefined });
});

getDataFromAPI()

import axios from "axios";

export const getDataFromAPI =(
  method: string,
  url: string,
  path: string,
  data?: any
) =>{
  switch (method) {
    case "create": {
      return axios
        .post(url + path, data, {
          headers: {
            Accept: "application/json",
            "content-type": "application/json"
          }
        })
        .catch(error => {
          throw error.response;
        });
    }

我试过用

jest.mock('../../src/Utilities/api');
const { callApi } = require('../../src/Utilities/api');


callApi.mockImplementation( () => console.log("some api call"));

我有错误

TypeError: Cannot read property 'mockImplementation' of undefined

  at Object.<anonymous> (src/Payments/PaymentSagas.spec.ts:10:17)
      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:188:7)

我经常

import * as apis from '../../src/Utilities/api';
jest.spyOn(api, "callApi");
api.callApi.mockImplementation(/* your mock */);

作为一个本身的函数很容易导出

export function spyUtil(obj, name, mockFunction = undefined) {
  const spy = jest.spyOn(obj, name);
  let mock;
  if (mockFunction) {
    mock = jest.fn(mockFunction);
    obj[name].mockImplementation(mock);
  }
  return { spy, mock };
}

和消耗品,在你的测试中

spyUtil(apis, "callApi", jest.fn())