原始问题
我正在按照Redux 文档中为异步操作创建者编写测试的示例进行操作。我尽可能地遵循这个例子,但我无法让测试工作。我收到以下错误消息:
TypeError: Cannot read property 'then' of undefined
(node:789) UnhandledPromiseRejectionWarning: Unhandled promise rejection
(rejection id: 28): TypeError: Cannot read property 'data' of undefined
这是我的动作创建者和测试的代码:
动作/index.js
import axios from 'axios';
import { browserHistory } from 'react-router';
import { AUTH_USER, AUTH_ERROR, RESET_AUTH_ERROR } from './types';
const API_HOST = process.env.NODE_ENV == 'production'
? http://production-server
: 'http://localhost:3090';
export function activateUser(token) {
return function(dispatch) {
axios.put(`${API_HOST}/activations/${token}`)
.then(response => {
dispatch({ type: AUTH_USER });
localStorage.setItem('token', response.data.token);
})
.catch(error => {
dispatch(authError(error.response.data.error));
});
}
}
export function authError(error) {
return {
type: AUTH_ERROR,
payload: error
}
}
确认测试.js
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import * as actions from '../../src/actions';
import { AUTH_USER, AUTH_ERROR, RESET_AUTH_ERROR } from
'../../src/actions/types';
import nock from 'nock';
import { expect } from 'chai';
const middlewares = [ thunk ];
const mockStore = configureMockStore(middlewares);
describe('Confirmation_Token action creator', () => {
afterEach(() => {
nock.cleanAll()
});
it('dispatches AUTH_USER', (done) => {
nock('http://localhost:3090')
.put('/activations/123456')
.reply(200, {
token: 7891011
});
const expectedActions = { type: AUTH_USER };
const store = mockStore({});
return store.dispatch(actions.activateUser(123456))
.then(() => { // return of async actions
expect(store.getActions()).toEqual(expectedActions);
done();
});
});
});
更新的问题
我已经部分(尽管不完全)弄清楚了这一点。我通过在调用return
前面添加一个语句axios
并注释掉localstorage.setItem
调用来实现这一点。
我还将分配给的对象转换expectedActions
为一个数组,并将我的断言从 更改toEqual
为to.deep.equal
。这是修改后的代码:
动作/index.js
export function activateUser(token) {
return function(dispatch) { // added return statement
return axios.put(`${API_HOST}/activations/${token}`)
.then(response => {
dispatch({ type: AUTH_USER });
// localStorage.setItem('token', response.data.token); Had to comment out local storage
})
.catch(error => {
dispatch(authError(error.response.data.error));
});
}
}
确认测试.js
describe('ConfirmationToken action creator', () => {
afterEach(() => {
nock.cleanAll()
});
it('dispatches AUTH_USER', (done) => {
nock('http://localhost:3090')
.put('/activations/123456')
.reply(200, {
token: 7891011
});
const expectedActions = [{ type: AUTH_USER }];
const store = mockStore({});
return store.dispatch(actions.activateUser(123456))
.then(() => { // return of async actions
expect(store.getActions()).to.deep.equal(expectedActions);
done();
});
});
});
但现在我无法在localStorage.setItem
不产生此错误消息的情况下进行测试:
Error: timeout of 2000ms exceeded. Ensure the done() callback is being called
in this test.
这是因为我需要模拟localStorage.setItem
吗?还是有一个我想念的更简单的解决方案?