Jest.js 模拟内部 axios ,create()

eulz3vhy  于 2023-01-18  发布在  Jest
关注(0)|答案(7)|浏览(209)

我正在使用jestaxios-mock-adapter测试redux异步操作创建器中的axios API调用。
当我使用axios.create()创建的axios示例时,我无法使它们工作:

import axios from 'axios';

const { REACT_APP_BASE_URL } = process.env;

export const ajax = axios.create({
  baseURL: REACT_APP_BASE_URL,
});

我会在我的async action creator中使用它,例如:

import { ajax } from '../../api/Ajax'

export function reportGet(data) {
  return async (dispatch, getState) => {
    dispatch({ type: REQUEST_TRANSACTION_DATA })

    try {
      const result = await ajax.post(
         END_POINT_MERCHANT_TRANSACTIONS_GET,
         data,
      )
      dispatch({ type: RECEIVE_TRANSACTION_DATA, data: result.data })
      return result.data
    } catch (e) {
      throw new Error(e);
    }
  }
}

下面是我的测试文件:

import {
  reportGet,
  REQUEST_TRANSACTION_DATA,
  RECEIVE_TRANSACTION_DATA,
} from '../redux/TransactionRedux'
import configureMockStore from 'redux-mock-store'
import thunk from 'redux-thunk'
import { END_POINT_MERCHANT_TRANSACTIONS_GET } from 'src/utils/apiHandler'
import axios from 'axios'
import MockAdapter from 'axios-mock-adapter'

const middlewares = [thunk]
const mockStore = configureMockStore(middlewares)
const store = mockStore({ transactions: {} })

test('get report data', async () => {
  let mock = new MockAdapter(axios)

  const mockData = {
    totalSalesAmount: 0
  }

  mock.onPost(END_POINT_MERCHANT_TRANSACTIONS_GET).reply(200, mockData)

  const expectedActions = [
    { type: REQUEST_TRANSACTION_DATA },
    { type: RECEIVE_TRANSACTION_DATA, data: mockData },
  ]

  await store.dispatch(reportGet())
  expect(store.getActions()).toEqual(expectedActions)
})

我只得到一个操作Received: [{"type": "REQUEST_TRANSACTION_DATA"}],因为ajax.post有一个错误。
我已经尝试了许多方法来嘲笑axios.create无济于事,没有真正知道我在做什么..任何帮助是赞赏.

3z6pesqy

3z6pesqy1#

好的,我知道了。下面是我是如何修复它的!我最终做了没有任何axios的模拟库!
src/__mocks__中为axios创建模拟:

// src/__mocks__/axios.ts

const mockAxios = jest.genMockFromModule('axios')

// this is the key to fix the axios.create() undefined error!
mockAxios.create = jest.fn(() => mockAxios)

export default mockAxios

然后在测试文件中,要点看起来像这样:

import mockAxios from 'axios'
import configureMockStore from 'redux-mock-store'
import thunk from 'redux-thunk'

// for some reason i need this to fix reducer keys undefined errors..
jest.mock('../../store/rootStore.ts')

// you need the 'async'!
test('Retrieve transaction data based on a date range', async () => {
  const middlewares = [thunk]
  const mockStore = configureMockStore(middlewares)
  const store = mockStore()

  const mockData = {
    'data': 123
  }

  /** 
   *  SETUP
   *  This is where you override the 'post' method of your mocked axios and return
   *  mocked data in an appropriate data structure-- {data: YOUR_DATA} -- which
   *  mirrors the actual API call, in this case, the 'reportGet'
   */
  mockAxios.post.mockImplementationOnce(() =>
    Promise.resolve({ data: mockData }),
  )

  const expectedActions = [
    { type: REQUEST_TRANSACTION_DATA },
    { type: RECEIVE_TRANSACTION_DATA, data: mockData },
  ]

  // work
  await store.dispatch(reportGet())

  // assertions / expects
  expect(store.getActions()).toEqual(expectedActions)
  expect(mockAxios.post).toHaveBeenCalledTimes(1)
})
zc0qhyus

zc0qhyus2#

如果您需要创建Jest测试,在特定测试中使用create模拟axios(并且不需要所有测试用例的模拟axios,如其他答案所述),您还可以用途:

const axios = require("axios");

jest.mock("axios");

beforeAll(() => {
    axios.create.mockReturnThis();
});

test('should fetch users', () => {
    const users = [{name: 'Bob'}];
    const resp = {data: users};
    axios.get.mockResolvedValue(resp);

    // or you could use the following depending on your use case:
    // axios.get.mockImplementation(() => Promise.resolve(resp))

    return Users.all().then(data => expect(data).toEqual(users));
});

下面是指向同一个示例的链接,该示例在Jest中模拟Axios,但没有create

lnxxn5zx

lnxxn5zx3#

下面是我对axios模拟

export default {
    defaults:{
        headers:{
            common:{
                "Content-Type":"",
                "Authorization":""
            }
        }
  },
  get: jest.fn(() => Promise.resolve({ data: {} })),
  post: jest.fn(() => Promise.resolve({ data: {} })),
  put: jest.fn(() => Promise.resolve({ data: {} })),
  delete: jest.fn(() => Promise.resolve({ data: {} })),
  create: jest.fn(function () {
      return {
          interceptors:{
              request : {  
                  use: jest.fn(() => Promise.resolve({ data: {} })),
              }
          },

          defaults:{
                headers:{
                    common:{
                        "Content-Type":"",
                        "Authorization":""
                    }
                }
          },
          get: jest.fn(() => Promise.resolve({ data: {} })),
          post: jest.fn(() => Promise.resolve({ data: {} })),
          put: jest.fn(() => Promise.resolve({ data: {} })),
          delete: jest.fn(() => Promise.resolve({ data: {} })),
      }
  }),
};
dzhpxtsq

dzhpxtsq4#

在你的mockAdapter中,你模拟了错误的示例,你应该模拟 AJAX ,像这样,const mock = MockAdapter(ajax)这是因为你现在模拟的不是axios示例,而是ajax,因为它是你用来发送请求的,也就是说,你在做export const ajax = axios.create...的时候创建了一个叫ajax的axios示例,所以既然你在代码中做的是const result = await ajax.post,应该模拟axios的ajax示例,而不是axios

zpgglvta

zpgglvta5#

我有另一个办法。

import {
  reportGet,
  REQUEST_TRANSACTION_DATA,
  RECEIVE_TRANSACTION_DATA,
} from '../redux/TransactionRedux'
import configureMockStore from 'redux-mock-store'
import thunk from 'redux-thunk'
import { END_POINT_MERCHANT_TRANSACTIONS_GET } from 'src/utils/apiHandler'
// import axios from 'axios'
import { ajax } from '../../api/Ajax' // axios instance
import MockAdapter from 'axios-mock-adapter'

const middlewares = [thunk]
const mockStore = configureMockStore(middlewares)
const store = mockStore({ transactions: {} })

test('get report data', async () => {
  // let mock = new MockAdapter(axios)
  let mock = new MockAdapter(ajax) // this here need to mock axios instance

  const mockData = {
    totalSalesAmount: 0
  }

  mock.onPost(END_POINT_MERCHANT_TRANSACTIONS_GET).reply(200, mockData)

  const expectedActions = [
    { type: REQUEST_TRANSACTION_DATA },
    { type: RECEIVE_TRANSACTION_DATA, data: mockData },
  ]

  await store.dispatch(reportGet())
  expect(store.getActions()).toEqual(expectedActions)
})
9q78igpj

9q78igpj6#

另一种方法:添加这个文件到src/__mocks__文件夹

import { AxiosStatic } from 'axios';

const axiosMock = jest.createMockFromModule<AxiosStatic>('axios');
axiosMock.create = jest.fn(() => axiosMock);

export default axiosMock;
hvvq6cgz

hvvq6cgz7#

下面的代码可以工作!

jest.mock("axios", () => {
        return {
            create: jest.fn(() => axios),
            post: jest.fn(() => Promise.resolve()),
        };
    });

相关问题