2017-07-05 2 views
4

Ich versuche, einen Test mit react, redux-mock-store und redux zu schreiben, aber ich bekomme immer Fehler. Vielleicht, weil meine Promise noch nicht gelöst wurde?Kann Eigenschaft '.then' von undefined beim Testen von Async-Aktionserstellern mit redux nicht lesen und reagieren

Der Action-Creator fetchListing() funktioniert tatsächlich, wenn ich es auf Dev und Produktion versuche, aber ich habe Probleme, den Test bestanden.

Fehlermeldung

(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) 

action/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) 
    }) 
    }) 
}) 

Dank im Voraus.

Antwort

6

store.dispatch(actions.fetchListings()) gibt undefined zurück. Sie können .then darauf nicht anrufen.

Siehe redux-thunk code. Sie führt die Funktion aus, die Sie zurückgeben, und gibt diese zurück. Die Funktion, die Sie in fetchListings zurückgeben, gibt nichts zurück, d. H. undefined.

Versuchen

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

Danach können Sie noch ein anderes Problem haben wird. Sie geben nichts zurück in Ihre then, Sie versenden nur. Das heißt, die nächste then bekommt undefined Argument

+0

'fetchListings()' tatsächlich funktioniert, wenn ich es verwenden - ich die Daten auf meinem app sehen - Aber gibt es eine bessere Möglichkeit, diese Funktion zu schreiben? Was ist mit "Test" selbst, wie kann ich es schreiben? – intercoder

+0

Das Schreiben von Tests für asynchronen Code kann eine Herausforderung darstellen. Einer der Hauptvorteile von redux-saga gegenüber redux-thunk ist die einfache Testbarkeit, daher sollten Sie diese Bibliothek überprüfen. –

+0

Sicheres Redux-Saga ist einfacher zu testen, weil es nur einfache Objekte verwendet, aber Redux-Thunk sollte einfach genug sein, um auch zu testen. Das Problem hier ist, wie er Versprechungen (und ein paar andere Dinge) handhabt. Siehe meine aktualisierte Antwort –

0

Ich weiß, das ist ein alter Thread. Aber ich denke, das Problem ist, dass Ihr Aktionsersteller nicht asynchron ist.

Versuchen:

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

Ich weiß auch, dies ist ein alter Thread, aber Sie müssen sicherstellen, dass Sie von der Asynchron-Aktion innerhalb Ihrer thunk zurückzukehren.

In meinem thunk Ich musste: Rückkehr holen()

die Aktion async und es funktionierte

Verwandte Themen