2017-09-22 2 views
0

Ich habe die folgende React-Komponente mit einem Redox-Speicher verbunden.Wie (anonyme) Funktion in Jest-Tests zu vergleichen?

import React, { Component } from 'react' 
import logo from './logo.svg' 
import './App.css' 
import { connect } from 'react-redux' 
import { getWeather } from './actions/WeatherActions' 
import WeatherComponent from './components/weatherComponent/WeatherComponent' 
import { get } from 'lodash' 

export class App extends Component { 

    componentDidMount() { 
    this.props.dispatch(getWeather()) 
    } 

    render() { 
    return (
     <div className="App"> 
      <div className="App-header"> 
      <img src={logo} className="App-logo" alt="logo" /> 
      <h2>Welcome to React</h2> 
      </div> 
      <WeatherComponent 
       weather={{ 
       location: get(this.props.weatherReducer.weather, 'name'), 
       temp: get(this.props.weatherReducer.weather, 'main.temp') 
       }} 
      /> 
     </div> 
    ) 
    } 
} 

export default connect((store) => { 
    return { 
    weatherReducer: store.weatherReducer, 
    } 
})(App) 

Diese Komponente entsendet die GetWeather Aktion mit dem componentDidMount Rückruf. Die getWeather Aktion gibt eine anonyme Methode zurück, wenn die Axiosversprechung aufgelöst wird.

import { GET_WEATHER_DONE, GET_WEATHER_ERROR } from './ActionTypes' 
import axios from 'axios' 

export function getWeather() { 
    let endpoint = 'http://api.openweathermap.org/data/2.5/weather?q=London&appid=2a345681ddcde393253af927097f5747' 

    return function (dispatch) { 
    return axios.get(endpoint) 
    .then((response) => { 
     return dispatch({ 
     type: GET_WEATHER_DONE, 
     payload: response.data 
     }) 
    }) 
    .catch((error) => { 
     return dispatch({ 
     type: GET_WEATHER_ERROR, 
     payload: error.response.data, 
     statuscode: error.response.status 
     }) 
    }) 
    } 
} 

Nein ich bei der Montage geschickt wird, um ein Gerät zu testen Überprüfung der GetWeather Aktion zu schreiben versuchen. Dieser Test sieht folgendermaßen aus und besteht.

import React from 'react' 
import ReactDOM from 'react-dom' 
import App from './App' 
import configureMockStore from 'redux-mock-store' 
import thunk from 'redux-thunk' 
import * as actions from './actions/WeatherActions' 

describe('app container',() => { 
    const store = configureMockStore([thunk])({ 
    weatherReducer: { 
     weather: {} 
    } 
    }) 

    const dispatchSpy = jest.fn() 
    store.dispatch = dispatchSpy 

    it('dispatches getWeather() action upon rendering',() => { 
    ReactDOM.render(<App store={store} />, document.createElement('div')) 

    expect(dispatchSpy.mock.calls[0][0].toString()).toEqual(actions.getWeather().toString()) 
    }) 

}) 

Wegen der Aktion eine anonyme Methode zurückkehrt, muss ich die toString Methode auf meine mock aufrufen, um die Aktionen zu vergleichen.

Ich habe diesen Test mit Snapshot-Tests neu erstellt.

import React from 'react' 
import ReactDOM from 'react-dom' 
import App from './App' 
import configureMockStore from 'redux-mock-store' 
import thunk from 'redux-thunk' 

describe('app container',() => { 
    const store = configureMockStore([thunk])({ 
    weatherReducer: { 
     weather: {} 
    } 
    }) 

    const dispatchSpy = jest.fn() 
    store.dispatch = dispatchSpy 

    it('dispatches correct actions upon rendering',() => { 
    ReactDOM.render(<App store={store} />, document.createElement('div')) 

    let tree = dispatchSpy.mock.calls.toString() 
    expect(tree).toMatchSnapshot(); 
    }) 


}) 

Wieder muss ich die toString Methode aufzurufen, in der folgenden Snapshot führt.

// Jest Snapshot v1, 

exports[`app container dispatches correct actions upon rendering 1`] = ` 
"function (dispatch) { 
    return _axios2.default.get(endpoint). 
    then(response => { 
     return dispatch({ 
     type: _ActionTypes.GET_WEATHER_DONE, 
     payload: response.data }); 

    }). 
    catch(error => { 
     return dispatch({ 
     type: _ActionTypes.GET_WEATHER_ERROR, 
     payload: error.response.data, 
     statuscode: error.response.status }); 

    }); 
    }" 
`; 

Nun, wenn Abdeckung ausgeführt wird, mit dem Garn Test - --coverage, mein Test wegen istanbul das Hinzufügen von Text zu meiner Aktion versagt. Die Ausgabe sieht wie folgt aus:

FAIL src/App.snapshot.test.js 
    ● app container › dispatches correct actions upon rendering 

    expect(value).toMatchSnapshot() 

    Received value does not match stored snapshot 1. 

    - Snapshot 
    + Received 

    -"function (dispatch) { 
    - return _axios2.default.get(endpoint). 
    - then(response => { 
    -  return dispatch({ 
    -  type: _ActionTypes.GET_WEATHER_DONE, 
    -  payload: response.data }); 
    +"function (dispatch) {/* istanbul ignore next */cov_2rypo7bhf.f[1]++;cov_2rypo7bhf.s[2]++; 
    + return (/* istanbul ignore next */_axios2.default.get(endpoint). 
    +  then(response => {/* istanbul ignore next */cov_2rypo7bhf.f[2]++;cov_2rypo7bhf.s[3]++; 
    +  return dispatch({ 
    +   type: /* istanbul ignore next */_ActionTypes.GET_WEATHER_DONE, 
    +   payload: response.data }); 

    - }). 
    - catch(error => { 
    -  return dispatch({ 
    -  type: _ActionTypes.GET_WEATHER_ERROR, 
    -  payload: error.response.data, 
    -  statuscode: error.response.status }); 
    +  }). 
    +  catch(error => {/* istanbul ignore next */cov_2rypo7bhf.f[3]++;cov_2rypo7bhf.s[4]++; 
    +  return dispatch({ 
    +   type: /* istanbul ignore next */_ActionTypes.GET_WEATHER_ERROR, 
    +   payload: error.response.data, 
    +   statuscode: error.response.status }); 

    - }); 
    +  })); 
     }" 

     at Object.it (src/App.snapshot.test.js:21:18) 
     at Promise.resolve.then.el (node_modules/p-map/index.js:46:16) 

Das Hauptproblem ich bin vor, ist die Tatsache, dass ich die toString Methode zum Vergleich aufrufen müssen. Was ist die richtige Methode für den Vergleich von (anonymen) Funktionen im Jest-Test?

Volle Quelle kann bei https://github.com/wvanvlaenderen/react-redux-weathercomponent

+0

Verlassen Sie sich in Ihrem Test nicht auf einen 'toString'-Cast. Schreiben Sie Code so, dass Sie Ihren Testcode problemlos darin einbinden können. – Halcyon

+1

Ich sehe, wie Sie 'dispatch' in' componentDidMount' aufrufen, aber wie ist 'getWeather' mit' dispatch'. Vielleicht ist es zu früh, Snapshot-Tests durchzuführen. Sie müssen stattdessen überprüfen, dass "Versand" mit den richtigen Aktionen aufgerufen wird –

Antwort

0

findet So konnte ich Testanrufe bei der Versendung durch die GetWeather Aktion in meinem Test verspotten, und die Art des Rückgabewertes auf einzelnen Anrufe zu überprüfen.

Snapshot-Tests wurden durch Rendern des Aufrufbaums auf dem Dispatch-Spion erzielt.

import React from 'react' 
import ReactDOM from 'react-dom' 
import App from './App' 
import { spy } from 'sinon' 
import configureMockStore from 'redux-mock-store' 
import thunk from 'redux-thunk' 
import * as actions from './actions/WeatherActions' 

describe('app container',() => { 
    const store = configureMockStore([thunk])({ 
    weatherReducer: { 
     weather: {} 
    } 
    }) 

    const dispatchSpy = spy(store, 'dispatch') 

    actions.getWeather = jest.fn().mockImplementation(() => { 
    return {type: 'fetching weather'} 
    }) 

    it('dispatches correct actions upon rendering',() => { 
    ReactDOM.render(<App store={store} />, document.createElement('div')) 

    expect(dispatchSpy.getCalls()).toMatchSnapshot(); 
    }) 

})