从数据库调度数据的 Redux 动作的单元测试
Unit test for Redux action which dispatches data from database
我有如下操作
index.js
export const dataCount = () => {
return async (dispatch) => {
getDataCount().then((data) => {
dispatch({ type: 'FETCH_DATA_COUNT', payload: data});
});
};
};
这里的 getDataCount 是一个辅助函数,returns 承诺从数据库中获取数据。
暂时我的测试是这样的
import configureStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import dataCount from '../index';
import getDataCount from '../helper';
const middlewares = [thunk];
const mockStore = configureStore(middlewares);
const store = mockStore();
let dataValue = '';
describe('fetchData', () => {
beforeEach(() => { // Runs before each test in the suite
dataValue = jest.fn(getDataCount);
store.clearActions();
});
it('has the correct action and payload for dataCount', async () => {
dataValue .mockReturnValue({ total : 13 });
const expectedActions = [
{
payload: dataValue(),
type: 'FETCH_DATA_COUNT'
}
];
await getDataCount().then((res) => {
store.dispatch(dataCount());
expect(store.getActions()).toEqual(expectedActions);
});
});
});
测试失败,因为 store.getActions() 返回 [],我知道我在调度时做错了什么。任何建议都会有很大帮助。
有一些事情我们可以通过这个测试做得更好。
你的 action creator 应该 return 我们在里面使用的 promise。如果我们这样做,我们可以将事情链接到调度上,以便在异步操作完成后发生。你的已经 return 一个承诺,因为它的 async 关键字,但这可能会导致时间问题。
export const dataCount = () => {
return async (dispatch) => {
return getDataCount().then((data) => {
dispatch({ type: 'FETCH_DATA_COUNT', payload: data });
});
};
};
第二个更改是将我们在测试中的断言链接到测试代码的调度后面。所以我们等待调度完全解决,然后比较动作。
it('has the correct action and payload for dataCount', async () => {
const expectedActions = [
{
payload: { total: 13 },
type: 'FETCH_DATA_COUNT'
}
];
// await the whole promise chain for jest to know how long to wait
await store.dispatch(dataCount())
.then(() => { // dispatch is resolved here
expect(store.getActions()).toEqual(expectedActions)
})
});
第三件事,dataValue
mock 并没有按照你的想法去做。要模拟此功能,您必须依赖注入它。在最简单的情况下,将它作为参数提供给 dataCount
。
store.dispatch(dataCount(dataValue))
依赖注入对您的单元测试很有用,因为现在测试将进入网络或任何地方 getDataCount
这会使您的测试变慢并且容易出错。
如果我有任何未解决的问题或错误,请告诉我。
我有如下操作
index.js
export const dataCount = () => {
return async (dispatch) => {
getDataCount().then((data) => {
dispatch({ type: 'FETCH_DATA_COUNT', payload: data});
});
};
};
这里的 getDataCount 是一个辅助函数,returns 承诺从数据库中获取数据。
暂时我的测试是这样的
import configureStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import dataCount from '../index';
import getDataCount from '../helper';
const middlewares = [thunk];
const mockStore = configureStore(middlewares);
const store = mockStore();
let dataValue = '';
describe('fetchData', () => {
beforeEach(() => { // Runs before each test in the suite
dataValue = jest.fn(getDataCount);
store.clearActions();
});
it('has the correct action and payload for dataCount', async () => {
dataValue .mockReturnValue({ total : 13 });
const expectedActions = [
{
payload: dataValue(),
type: 'FETCH_DATA_COUNT'
}
];
await getDataCount().then((res) => {
store.dispatch(dataCount());
expect(store.getActions()).toEqual(expectedActions);
});
});
});
测试失败,因为 store.getActions() 返回 [],我知道我在调度时做错了什么。任何建议都会有很大帮助。
有一些事情我们可以通过这个测试做得更好。
你的 action creator 应该 return 我们在里面使用的 promise。如果我们这样做,我们可以将事情链接到调度上,以便在异步操作完成后发生。你的已经 return 一个承诺,因为它的 async 关键字,但这可能会导致时间问题。
export const dataCount = () => {
return async (dispatch) => {
return getDataCount().then((data) => {
dispatch({ type: 'FETCH_DATA_COUNT', payload: data });
});
};
};
第二个更改是将我们在测试中的断言链接到测试代码的调度后面。所以我们等待调度完全解决,然后比较动作。
it('has the correct action and payload for dataCount', async () => {
const expectedActions = [
{
payload: { total: 13 },
type: 'FETCH_DATA_COUNT'
}
];
// await the whole promise chain for jest to know how long to wait
await store.dispatch(dataCount())
.then(() => { // dispatch is resolved here
expect(store.getActions()).toEqual(expectedActions)
})
});
第三件事,dataValue
mock 并没有按照你的想法去做。要模拟此功能,您必须依赖注入它。在最简单的情况下,将它作为参数提供给 dataCount
。
store.dispatch(dataCount(dataValue))
依赖注入对您的单元测试很有用,因为现在测试将进入网络或任何地方 getDataCount
这会使您的测试变慢并且容易出错。
如果我有任何未解决的问题或错误,请告诉我。