模拟axios获取带有queryParams的query请求

时间:2018-08-23 10:37:38

标签: reactjs unit-testing redux axios jestjs

我正在尝试测试从Firebase获取数据的异步Redux动作。 我用玩笑和moxios模拟异步调用

actionTypes.js

out

order.js

export const FETCH_ORDERS_START = 'FETCH_ORDERS_START'
export const FETCH_ORDERS_SUCCESS = 'FETCH_ORDERS_SUCCESS'
export const FETCH_ORDERS_FAILED = 'FETCH_ORDERS_FAILED'

在我的测试中,我希望调用import * as actionTypes from './actionTypes' import axios from './../../axios-orders' export const fetchOrdersSuccess = (orders) => { return { type: actionTypes.FETCH_ORDERS_SUCCESS, orders: orders, } } export const fetchOrdersFailed = (error) => { return { type: actionTypes.FETCH_ORDERS_FAILED, error: error, } } export const fetchOrdersStart = () => { return { type: actionTypes.FETCH_ORDERS_START, } } export const fetchOrders = (token, userId) => { return dispatch => { dispatch(fetchOrdersStart()) const queryParams = `?auth=${token}&orderBy="userId"&equalTo="${userId}"` axios.get('/orders.json' + queryParams) .then(resp => { const fetchedData = [] for (let key in resp.data) { fetchedData.push({ ...resp.data[key], id: key, }) } dispatch(fetchOrdersSuccess(fetchedData)) }) .catch( error => dispatch(fetchOrdersFailed(error))) } } 会带来两个还原动作:START和SUCCESS

fetchOrders(token, userId)

不幸的是,它似乎总是会产生成功和失败的动作。如何使用queryParameters正确模拟axios调用。 在import moxios from 'moxios'; import thunk from 'redux-thunk'; import configureMockStore from 'redux-mock-store'; import * as actionTypes from './actionTypes'; import * as actions from './order' const middlewares = [thunk]; const mockStore = configureMockStore(middlewares); const ordersMock = { "-LGyxbZUSr5Q4jboj0uw" : { "ingredients" : { "bacon" : 0, "cheese" : 0, "meat" : 1, "salad" : 0 }, } } describe('order actions', () => { beforeEach(function () { moxios.install(); }); afterEach(function () { moxios.uninstall(); }); it('creates FETCH_ORDER_SUCCESS after successfuly fetching orders', () => { moxios.wait(() => { const request = moxios.requests.mostRecent(); request.respondWith({ status: 200, response: ordersMock, }); }); const expectedActions = [ { type: actionTypes.FETCH_ORDERS_START }, { type: actionTypes.FETCH_ORDERS_SUCCESS, orders: ordersMock }, ]; const store = mockStore({ posts: {} }) store.dispatch(actions.fetchOrders("TOKEN", "USER_ID")) console.log(store.getActions()) expect(store.getActions()).toEqual(expectedActions); }) }) 中,使用我自己的axios实例,并设置其基本名称:

fetchOrders

1 个答案:

答案 0 :(得分:0)

这里是仅使用jestjstypescript而不使用maxios模块的解决方案。

order.ts

import * as actionTypes from './actionTypes';
import axios from 'axios';

export const fetchOrdersSuccess = orders => {
  return {
    type: actionTypes.FETCH_ORDERS_SUCCESS,
    orders
  };
};

export const fetchOrdersFailed = error => {
  return {
    type: actionTypes.FETCH_ORDERS_FAILED,
    error
  };
};
export const fetchOrdersStart = () => {
  return {
    type: actionTypes.FETCH_ORDERS_START
  };
};

export const fetchOrders = (token, userId) => {
  return dispatch => {
    dispatch(fetchOrdersStart());
    const queryParams = `?auth=${token}&orderBy="userId"&equalTo="${userId}"`;
    return axios
      .get('/orders.json' + queryParams)
      .then(resp => {
        dispatch(fetchOrdersSuccess(resp));
      })
      .catch(error => dispatch(fetchOrdersFailed(error)));
  };
};

order.spec.ts

import thunk, { ThunkDispatch } from 'redux-thunk';
import configureMockStore from 'redux-mock-store';
import * as actionTypes from './actionTypes';
import * as actions from './order';
import { AnyAction } from 'redux';
import axios from 'axios';

type State = any;
const middlewares = [thunk];
const mockStore = configureMockStore<State, ThunkDispatch<State, undefined, AnyAction>>(middlewares);

const ordersMock = {
  '-LGyxbZUSr5Q4jboj0uw': {
    ingredients: {
      bacon: 0,
      cheese: 0,
      meat: 1,
      salad: 0
    }
  }
};

describe('order actions', () => {
  afterEach(() => {
    jest.restoreAllMocks();
  });
  it('creates FETCH_ORDER_SUCCESS after successfuly fetching orders', () => {
    expect.assertions(2);
    const getSpy = jest.spyOn(axios, 'get').mockResolvedValueOnce(ordersMock);
    const expectedActions = [
      { type: actionTypes.FETCH_ORDERS_START },
      { type: actionTypes.FETCH_ORDERS_SUCCESS, orders: ordersMock }
    ];

    const store = mockStore({ posts: {} });

    return store.dispatch(actions.fetchOrders('TOKEN', 'USER_ID')).then(() => {
      expect(store.getActions()).toEqual(expectedActions);
      expect(getSpy).toBeCalledWith('/orders.json?auth=TOKEN&orderBy="userId"&equalTo="USER_ID"');
    });
  });
});

带有覆盖率报告的单元测试结果:

 PASS  src/stackoverflow/51983850/order.spec.ts (7.79s)
  order actions
    ✓ creates FETCH_ORDER_SUCCESS after successfuly fetching orders (8ms)

----------------|----------|----------|----------|----------|-------------------|
File            |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------------|----------|----------|----------|----------|-------------------|
All files       |    88.89 |      100 |    71.43 |    88.89 |                   |
 actionTypes.ts |      100 |      100 |      100 |      100 |                   |
 order.ts       |    86.67 |      100 |    71.43 |    86.67 |             12,32 |
----------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        11.753s, estimated 19s

源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/51983850