2016-08-17 10 views
11

Ich verwende Enzyme, um meine React-Komponenten zu testen. Ich verstehe, dass ich, um die rohe, nicht verbundene Komponente zu testen, sie einfach exportieren und testen müsste (das habe ich getan). Ich habe es geschafft, einen Test für die angeschlossene Komponente zu schreiben, aber ich bin mir nicht sicher, ob das der richtige Weg ist und was genau ich für die angeschlossene Komponente testen möchte.Redux: Wie man eine verbundene Komponente prüft?

Container.jsx

import {connect} from 'react-redux'; 
import Login from './Login.jsx'; 
import * as loginActions from './login.actions'; 

const mapStateToProps = state => ({ 
    auth: state.auth 
}); 
const mapDispatchToProps = dispatch => ({ 
    loginUser: credentials => dispatch(loginActions.loginUser(credentials)) 

}); 
export default connect(mapStateToProps, mapDispatchToProps)(Login); 

Container.test.js

import React from 'react'; 
import {Provider} from 'react-redux'; 
import {mount, shallow} from 'enzyme'; 
import {expect} from 'chai'; 
import LoginContainer from '../../src/login/login.container'; 
import Login from '../../src/login/Login'; 


describe('Container Login',() => { 
    it('should render the container component',() => { 
    const storeFake = state => ({ 
     default:() => { 
     }, 
     subscribe:() => { 
     }, 
     dispatch:() => { 
     }, 
     getState:() => ({ ...state }) 
    }); 
    const store = storeFake({ 
     auth: { 
     sport: 'BASKETBALL' 
     } 
    }); 

    const wrapper = mount(
     <Provider store={store}> 
     <LoginContainer /> 
     </Provider> 
    ); 

    expect(wrapper.find(LoginContainer).length).to.equal(1); 
    const container = wrapper.find(LoginContainer); 
    expect(container.find(Login).length).to.equal(1); 
    expect(container.find(Login).props().auth).to.eql({ sport: 'BASKETBALL' }); 
    }); 
}); 

Antwort

12

Dies ist eine interessante Frage.

Normalerweise importiere ich sowohl den Container als auch die Komponente, um den Test durchzuführen. Für Container-Tests verwende ich redux-mock-store. Komponententests dienen zum Testen von asynchronen Funktionen. In Ihrem Fall ist der Anmeldeprozess beispielsweise eine asynchrone Funktion mit sinon Stubs. Hier ist ein Ausschnitt desselben,

import React from 'react'; 
import {Provider} from 'react-redux'; 
import {mount, shallow} from 'enzyme'; 
import {expect} from 'chai'; 
import LoginContainer from '../../src/login/login.container'; 
import Login from '../../src/login/Login'; 
import configureMockStore from 'redux-mock-store'; 
import thunk from 'redux-thunk'; 
import { stub } from 'sinon'; 

const mockStore = configureMockStore([thunk]); 

describe('Container Login',() => { 
    let store; 
    beforeEach(() => { 
    store = mockStore({ 
     auth: { 
     sport: 'BASKETBALL', 
     }, 
    }); 
    }); 
    it('should render the container component',() => { 
    const wrapper = mount(
     <Provider store={store}> 
     <LoginContainer /> 
     </Provider> 
    ); 

    expect(wrapper.find(LoginContainer).length).to.equal(1); 
    const container = wrapper.find(LoginContainer); 
    expect(container.find(Login).length).to.equal(1); 
    expect(container.find(Login).props().auth).to.eql({ sport: 'BASKETBALL' }); 
    }); 

    it('should perform login',() => { 
    const loginStub = stub().withArgs({ 
     username: 'abcd', 
     password: '1234', 
    }); 
    const wrapper = mount(<Login 
     loginUser={loginStub} 
    />); 
    wrapper.find('button').simulate('click'); 
    expect(loginStub.callCount).to.equal(1); 
    }); 
}); 
+0

Würden das die Tests für mapStateToProps und mapDispatch ausreichen? – Umair

+0

Ja in der Tat .. Sie müssen mit einem Coverage-Tool überprüfen, finden Sie, dass es vollständig abgedeckt ist – anoop

+1

Die eigentliche Sache, die ich wissen möchte, ist im Grunde Was testen, wenn wir die Container/Smart-Komponente testen werden? – Umair

1

Wie Sie wies darauf hin, ich die Art und Weise in der Regel tun dies ist die un-angeschlossene Komponente zu exportieren als gut, und testen Sie das.

heißt

export {Login}; 

Hier ist ein Beispiel. Source of the component und source of the tests.

Für die umschlossene Komponente, ich erstelle keine Tests für diese, weil meine Mappings (mapStateToProps und mapDispatchToProps) im Allgemeinen sehr einfach sind. Wenn ich eine umschlossene Komponente testen wollte, würde ich diese Karten wirklich nur testen. Das ist, was ich wählen würde, um explizit zu testen, anstatt die gesamte Komponente in einem eingepackten Formular erneut zu testen.

Es gibt zwei Möglichkeiten, diese Funktionen zu testen. Ein Weg wäre, die Funktionen innerhalb des Moduls selbst zu exportieren.

d.h.

export {mapStateToProps, mapDispatchToProps}

Ich bin kein großer Fan von diesem, weil ich keine anderen Module in der App auf sie zugreifen wollen. In meinen Tests verwende ich manchmal babel-plugin-rewire, um auf "in-scope" -Variablen zuzugreifen, also würde ich das in dieser Situation tun.

, dass so etwas aussehen könnte:

import { 
    Login, __Rewire__ 
} 

const mapStateToProps = __Rewire__.__get__('mapStateToProps'); 

describe('mapStateToProps',() => { ... }); 
+0

Ich habe das getan. 'Import Login from ../ login' ist die nicht verbundene Komponente. Der Grund, warum ich {Login} nicht verwendet habe, ist, dass sie in separaten Dateien liegen. – Umair

+0

Was genau muss ich auch für die Container-Komponente testen? – Umair

+0

Oh, ich verstehe was du meinst. Bis jetzt habe ich diese tbqh noch nicht getestet. Wenn ich sie testen würde, würde ich etwas wie "babel-plugin-rewire" verwenden und "mapStateToProps" und "mapDispatchToProps" anstelle der umschlossenen Komponente selbst testen. – jmeas

Verwandte Themen