繁体   English   中英

使用 moxios 使用 queryParams 模拟 axios 获取请求

[英]Mock axios get request with queryParams with moxios

我正在尝试测试从 Firebase 获取数据的异步 Redux 操作。 我使用 jest 和 moxios 来模拟异步调用

动作类型.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'

订单.js

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)))
  }
}

在我的测试中,我希望调用fetchOrders(token, userId)会产生两个 redux 操作:START 和 SUCCESS

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);
    })
})

不幸的是,它似乎总是会创建成功和失败的操作。 如何使用 queryParameters 正确模拟 axios 调用。 fetchOrders中使用我自己的 axios 实例并设置了 base-name:

import axios from 'axios'

const instance = axios.create({
  baseURL: 'https://urltofirebase.com'
})

export default instance

这里是解决方案仅使用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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM