我正在尝试测试从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
答案 0 :(得分:0)
这里是仅使用jestjs
和typescript
而不使用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