2016-07-13 15 views
1

Ich habe meinen Test geschrieben, um asynchrone Aktionen zu testen. Ich bin derzeit die folgende Fehlermeldung erhalten TypeError: Cannot read poperty 'then' of undefined und es zeigt auf die folgende Zeile in meinem CodeReact Redux async Aktionstest

return store.dispatch(actions.fetchMovies()).then(() => { 

Hier ist mein Code:

async Aktionen 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); 
     }); 
    }); 
}); 

Aktionen:

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 
     }); 
    }); 
    }; 
}; 

Dies ist das erste Mal testen Async-Aktionen, so dass ich nicht sicher bin w es läuft falsch.

+0

Ich möchte nur Redux-Saga http://yelouafi.github.io/redux-saga/ erwähnen, um Ihren asynchronen Aktionsfluss zu bewältigen. Ein Teil seines Vorteils ist die Leichtigkeit, mit der Sie jeden Teil einer asynchronen Aktion testen können. –

Antwort

0

Verwenden Sie redux-mock-store anstelle von redux createStore(). Dies ist ein Mock-Store zum Testen von Async-Aktionserstellern und Middleware. Die Github-Seite enthält auch einige Beispiele zur Verwendung.

EDIT:

Was passiert, wenn Sie Ihre Aktion Schöpfer so ändern, dass sie das Ergebnis der axios.get(MOVIES_API) zurückkehren?

+0

Ich versuchte zuerst redux-mock-store und hatte das gleiche passiert. Deshalb habe ich einfach einen normalen Laden eingerichtet, weil ich das in einem Beispiel gesehen habe. Und ich sollte nicht ändern müssen, was die Aktion zurückgibt, um diese Arbeit zu machen ... die Aktionen funktionieren gut – erichardson30

+0

Ich denke, du solltest es versuchen. Sie können kein weiteres 'then()' verketten, wenn Ihr Aktionsersteller das Versprechen nicht zurückgibt. – Steve

+0

schrieb es um und der Test läuft, jetzt bekomme ich einen Fehler 'Fehler: Nock: Keine Übereinstimmung für die Anfrage erhalten https: //api.themoviedb .... ' – erichardson30

2

Es ist, weil Ihre Aktion kein Versprechen zurückgibt - ändern Sie Ihre Aktion, um ein Versprechen zurückzugeben, das erwartet werden kann. Dies ist nicht erforderlich, aber wenn Sie wissen möchten, wann Ihr API-Aufruf abgeschlossen wurde (dh Ihr Komponententest möchte in diesem speziellen Fall wissen), können Sie ein Versprechen als praktischen Nebeneffekt der Aktion zurückgeben:

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 
     }); 
    }); 
    }; 
} 

;