2017-07-05 1 views
4

J'essaye d'écrire un test en utilisant reaux, redux-mock-store et redux, mais je continue d'obtenir et d'erreur. Peut-être parce que mon Promise n'a pas encore été résolu?Impossible de lire la propriété '.then' de undefined lors du test des créateurs d'action asynchrones avec redux et de réagir

Le créateur d'action fetchListing() fonctionne quand je l'essaie sur le développement et la production, mais j'ai des problèmes pour réussir le test.

message d'erreur

(node:19143) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 3): SyntaxError 
(node:19143) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code. 
FAIL src/actions/__tests__/action.test.js 
    ● async actions › creates "FETCH_LISTINGS" when fetching listing has been done 

    TypeError: Cannot read property 'then' of undefined 

     at Object.<anonymous> (src/actions/__tests__/action.test.js:44:51) 
      at Promise (<anonymous>) 
     at Promise.resolve.then.el (node_modules/p-map/index.js:42:16) 
      at <anonymous> 
     at process._tickCallback (internal/process/next_tick.js:169:7) 

    async actions 
    ✕ creates "FETCH_LISTINGS" when fetching listing has been done (10ms) 

actions /index.js

// actions/index.js 
import axios from 'axios'; 

import { FETCH_LISTINGS } from './types'; 

export function fetchListings() { 

    const request = axios.get('/5/index.cfm?event=stream:listings'); 

    return (dispatch) => { 
    request.then(({ data }) => { 
     dispatch({ type: FETCH_LISTINGS, payload: data }); 
    }); 
    } 
}; 

action.test.js

// actions/__test__/action.test.js 

import configureMockStore from 'redux-mock-store'; 
import thunk from 'redux-thunk'; 
import { applyMiddleware } from 'redux'; 
import nock from 'nock'; 
import expect from 'expect'; 

import * as actions from '../index'; 
import * as types from '../types'; 


const middlewares = [ thunk ]; 
const mockStore = configureMockStore(middlewares); 

describe('async actions',() => { 
    afterEach(() => { 
    nock.cleanAll() 
}) 


it('creates "FETCH_LISTINGS" when fetching listing has been done',() => { 
    nock('http://example.com/') 
    .get('/listings') 
    .reply(200, { body: { listings: [{ 'corpo_id': 5629, id: 1382796, name: 'masm' }] } }) 

    const expectedActions = [ 
     { type: types.FETCH_LISTINGS }, { body: { listings: [{ 'corpo_id': 5629, id: 1382796, name: 'masm' }] }} 
    ] 

    const store = mockStore({ listings: [] }) 

    return store.dispatch(actions.fetchListings()).then((data) => { 
     expect(store.getActions()).toEqual(expectedActions) 
    }) 
    }) 
}) 

Merci en avance.

Répondre

6

store.dispatch(actions.fetchListings()) renvoie undefined. Vous ne pouvez pas appeler .then à ce sujet.

Voir redux-thunk code. Il exécute la fonction que vous retournez et la retourne. La fonction que vous renvoyez dans fetchListings ne renvoie rien, c'est-à-dire undefined.

Essayez

return (dispatch) => { 
    return request.then((data) => { 
     dispatch({ type: FETCH_LISTINGS, payload: data }); 
    }); 
    } 

Après que vous aurez toujours un autre problème. Vous ne retournez rien à l'intérieur de votre then, vous l'envoyez seulement. Cela signifie que le prochain then obtient undefined argument

+0

'fetchListings()' fonctionne réellement quand je l'utilise - je peux voir les données sur mon application - mais y a-t-il un meilleur moyen d'écrire cette fonction? Qu'en est-il de 'test' lui-même comment puis-je l'écrire? – intercoder

+0

L'écriture de tests pour le code asynchrone peut être difficile. L'un des points de vente principaux de redux-saga sur redux-thunk est la facilité de test, vous pouvez donc vouloir vérifier cette bibliothèque. –

+0

Sure redux-saga est plus facile à tester car il utilise simplement des objets simples, mais redux-thunk devrait être assez facile à tester. Le problème ici est de savoir comment il gère les promesses (et quelques autres choses). Voir ma mise à jour –

0

Je sais que c'est un ancien fil de discussion. Mais je pense que le problème est que votre créateur d'action n'est pas asynchrone.

Essayez:

export async function fetchListings() { 
    const request = axios.get('/5/index.cfm?event=stream:listings'); 
    return (dispatch) => { 
    request.then(({ data }) => { 
     dispatch({ type: FETCH_LISTINGS, payload: data }); 
    }); 
    } 
} 
1

Je sais aussi que c'est un vieux fil, mais vous devez vous assurer que vous retournez l'action async intérieur de votre thunk.

Dans mon thunk je devais: retour fetch()

l'action async et cela a fonctionné