【问题标题】:How to mock an axios class如何模拟 axios 类
【发布时间】:2019-04-15 20:59:37
【问题描述】:

我正在为我的异步操作编写测试。我已将我的 axios 调用抽象为一个单独的类。如果我想测试我的异步 redux 操作,如何为 api.js 编写一个模拟以便 sampleAction.test.js 能够通过?谢谢!

api.js:

import axios from 'axios';

let apiUrl = '/api/';
if (process.env.NODE_ENV === 'test') {
  apiUrl = 'http://localhost:8080/api/';
}

export default class Api {
  static async get(url) {
    const response = await axios.get(`${apiUrl}${url}`, {withCredentials: true});
    return response;
  }
}

sampleAction.js: 从'./api'导入API;

export const fetchData = () => async (dispatch) => {
  try {
    const response = await Api.get('foo');
    dispatch({
      type: 'RECEIVE_DATA',
      data: response.data.data,
    });
  } catch (error) {
    handleError(error);
  }
};

sampleAction.test.js:

import store from './store';

test('testing RECEIVE_DATA async action', () => {
  const expectedActions = [
    { type: 'RECEIVE_DATA', data: 'payload' },
  ];
  return store.dispatch(actions.fetchData()).then(() => {
    expect(store.getActions()).toEqual(expectedActions);
  });
});

【问题讨论】:

  • 你看过github.com/axios/moxios吗?
  • 谢谢@CharlieStanard,我确实看过了。我看到它引用了模拟 axios.create() 实例,但是,我对这是否是我应该用于模拟的那种东西以及如何做到这一点感到很困惑。我的意思是,如果我调用那个模拟,会发生什么?难道我不想让它模拟传入的url并返回某个值吗?

标签: javascript redux jestjs axios moxios


【解决方案1】:

你可以像这样模拟Api.get

import { fetchData } from './sampleAction';
import Api from './api';

let getMock;
beforeEach(() => {
  getMock = jest.spyOn(Api, 'get');
  getMock.mockResolvedValue({ data: { data: 'mock data' } });
});
afterEach(() => {
  getMock.mockRestore();
});

test('testing RECEIVE_DATA async action', async () => {
  const dispatch = jest.fn();
  await fetchData()(dispatch);
  expect(getMock).toHaveBeenCalledWith('foo');  // Success!
  expect(dispatch).toHaveBeenCalledWith({
    type: 'RECEIVE_DATA',
    data: 'mock data'
  });  // Success!
});

...或者您可以像这样模拟api.js

import { fetchData } from './sampleAction';
import Api from './api';

jest.mock('./api', () => ({
  get: jest.fn(() => Promise.resolve({ data: { data: 'mock data' } }))
}));

test('testing RECEIVE_DATA async action', async () => {
  const dispatch = jest.fn();
  await fetchData()(dispatch);
  expect(Api.get).toHaveBeenCalledWith('foo');  // Success!
  expect(dispatch).toHaveBeenCalledWith({
    type: 'RECEIVE_DATA',
    data: 'mock data'
  });  // Success!
});

...或者你可以自动模拟api.js并填写Api.get的返回值:

import { fetchData } from './sampleAction';
import Api from './api';

jest.mock('./api');  // <= auto-mock
Api.get.mockResolvedValue({ data: { data: 'mock data' } });

test('testing RECEIVE_DATA async action', async () => {
  const dispatch = jest.fn();
  await fetchData()(dispatch);
  expect(Api.get).toHaveBeenCalledWith('foo');  // Success!
  expect(dispatch).toHaveBeenCalledWith({
    type: 'RECEIVE_DATA',
    data: 'mock data'
  });  // Success!
});

...或者您可以在./__mocks__/api.js 创建一个manual mock

export default {
  get: jest.fn(() => Promise.resolve({ data: { data: 'mock data' } }))
}

...并像这样在您的测试中激活它:

import { fetchData } from './sampleAction';
import Api from './api';

jest.mock('./api');  // <= activate manual mock

test('testing RECEIVE_DATA async action', async () => {
  const dispatch = jest.fn();
  await fetchData()(dispatch);
  expect(Api.get).toHaveBeenCalledWith('foo');  // Success!
  expect(dispatch).toHaveBeenCalledWith({
    type: 'RECEIVE_DATA',
    data: 'mock data'
  });  // Success!
});

【讨论】:

  • 感谢@brian-lives-outdoors,这太棒了!
猜你喜欢
  • 2021-03-28
  • 2019-12-09
  • 2020-08-23
  • 2018-12-18
  • 1970-01-01
  • 2019-11-14
  • 2019-06-26
  • 2023-04-02
  • 1970-01-01
相关资源
最近更新 更多