问题
I have my test written to test async actions. I'm currently getting the following error TypeError: Cannot read poperty 'then' of undefined and it is pointing to the following line in my code
return store.dispatch(actions.fetchMovies()).then(() => {
Here is my code :
async actions test :
import { createStore, applyMiddleware } from 'redux';
import initialState from '../reducers/initialState';
import rootReducer from '../reducers/index';
import thunk from 'redux-thunk';
import * as actions from './actions';
import * as ActionTypes from '../constants/constants';
import nock from 'nock';
import { expect } from 'chai';
import API_KEY from '../config/config';
const MOVIES_API = 'https://api.themoviedb.org/3/discover/movie?api_key='+API_KEY;
describe('async actions', () => {
afterEach(() => {
nock.cleanAll();
});
it('creates FETCH_MOVIES_SUCCESS when fetching movies is complete', () => {
nock(MOVIES_API)
.get()
.reply(200, {data: {results: [{title: 'Batman vs Superman'}]}});
const expectedActions = [
{ type: ActionTypes.FETCH_MOVIES },
{ type: ActionTypes.FETCH_MOVIES_SUCCESS, data: {results: [{title: 'Batman vs Superman'}]}}
];
const store = createStore(rootReducer, initialState, applyMiddleware(thunk));
return store.dispatch(actions.fetchMovies()).then(() => {
expect(store.getActions()).to.deep.equal(expectedActions);
});
});
});
actions:
import axios from 'axios';
import * as constants from '../constants/constants';
import API_KEY from '../config/config';
export const fetchMovies = () => {
const MOVIES_API = 'https://api.themoviedb.org/3/discover/movie?api_key='+ API_KEY;
return dispatch => {
dispatch({
type: constants.FETCH_MOVIES
});
axios.get(MOVIES_API).then(function(response) {
dispatch({
type: constants.FETCH_MOVIES_SUCCESS,
data: response.data.results
});
})
.catch(function(res) {
dispatch({
type: constants.FETCH_MOVIES_ERROR,
msg: res.message
});
});
};
};
This is the first time testing async actions so I'm not sure what's going wrong.
回答1:
Try using redux-mock-store instead of redux createStore(). This is a mock store for testing async action creators and middleware. The Github page also includes some examples how to use it.
EDIT:
What happens when you modify your action creator so that it returns the result of axios.get(MOVIES_API)?
回答2:
It's because your action doesn't return a promise - change your action to return a promise that can be awaited. This isn't required, but if you want to know when your API call has completed (i.e. your unit test wants to know in this particular case), then you can return a promise as a convenience side effect of the action:
export const fetchMovies = () => {
const MOVIES_API = 'https://api.themoviedb.org/3/discover/movie?api_key='+ API_KEY;
return dispatch => {
dispatch({
type: constants.FETCH_MOVIES
});
// Return a promise
return axios.get(MOVIES_API).then(function(response) {
dispatch({
type: constants.FETCH_MOVIES_SUCCESS,
data: response.data.results
});
})
.catch(function(res) {
dispatch({
type: constants.FETCH_MOVIES_ERROR,
msg: res.message
});
});
};
}
;
来源:https://stackoverflow.com/questions/38355847/react-redux-async-action-testing