我从单元测试和Jest开始。我想要的是在从db获取一些资源后测试操作的响应。
这是行动代码:
export function loadPortlets() {
return function(dispatch) {
return portletApi.getAllPortlets().then(response => {
dispatch(loadPortletsSuccess(response));
dispatch(hideLoading());
}).catch(error => {
dispatch({ type: null, error: error });
dispatch(hideLoading());
throw(error);
});
};
}
此代码从以下位置获取数据:
static getAllPortlets() {
return fetch(`${API_HOST + API_URI}?${RES_TYPE}`)
.then(response =>
response.json().then(json => {
if (!response.ok) {
return Promise.reject(json);
}
return json;
})
);
}
这是测试:
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import fetch from 'isomorphic-fetch';
import fetchMock from 'fetch-mock';
import * as actions from '../portletActions';
import * as types from '../actionTypes';
const middlewares = [thunk];
const mockStore = configureMockStore(middlewares);
const mockResponse = (status, statusText, response) => {
return new window.Response(response, {
status: status,
statusText: statusText,
headers: {
'Content-type': 'application/json'
}
});
};
describe('async actions', () => {
afterEach(() => {
fetchMock.reset();
fetchMock.restore();
})
it('calls request and success actions if the fetch response was successful', () => {
window.fetch = jest.fn().mockImplementation(() =>
Promise.resolve(mockResponse(200, null, [{ portlets: ['do something'] }])));
const store = mockStore({ portlets: []});
return store.dispatch(actions.loadPortlets())
.then(() => {
const expectedActions = store.getActions();
expect(expectedActions[0]).toContain({ type: types.LOAD_PORTLETS_SUCCESS });
})
});
});
这是运行测试的结果:
FAIL src\actions\__tests__\portletActions.tests.js
● async actions › calls request and success actions if the fetch response was successful
expect(object).toContain(value)
Expected object:
{"portlets": [// here an array of objects], "type": "LOAD_PORTLETS_SUCCESS"}
To contain value:
{"type": "LOAD_PORTLETS_SUCCESS"}
at store.dispatch.then (src/actions/__tests__/portletActions.tests.js:56:34)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:188:7)
在此示例的redux文档(https://redux.js.org/recipes/writing-tests)中,他们收到的结果只包含已执行的操作类型,但我得到的是真实数据以及数组中的操作
所以我不确定代码是错误的,还是测试,或者两者兼而有之!
在此先感谢,非常感谢任何帮助!
答案 0 :(得分:0)
您使用此单元测试进行了太多测试。我看到你正在使用thunks它看起来像你可以改变你的fetch作为一个模块传递到thunk并做这样的事情。我用过茉莉花,但基本上是一样的。你不想在这里嘲笑你的商店只是行动和派遣。单元测试的重点应该是测试异步操作,而不是测试从db或redux存储交互中获取实际数据,这样你就可以将所有这些存根。“/ p>
作为参考,configureStore看起来像这样......
const createStoreWithMiddleware = compose(
applyMiddleware(thunk.withExtraArgument({ personApi }))
)(createStore);
测试案例......
it('dispatches an action when receiving', done => {
const person = [{ firstName: 'Francois' }];
const expectedAction = {
type: ActionTypes.RECEIVED,
payload: {
people,
},
};
const dispatch = jasmine.createSpy();
const promise = Q.resolve(person);
const personApi = {
fetchPerson: jasmine
.createSpy()
.and.returnValue(promise),
};
const thunk = requestPerson();
thunk(dispatch, undefined, { personApi });
promise.then(() => {
expect(dispatch.calls.count()).toBe(2);
expect(dispatch.calls.mostRecent().args[0]).toEqual(expectedAction);
done();
});
});