2016-11-15 5 views
1

Ich habe die folgende intelligente Komponente, die die Lebenszyklusmethode componentWillMount verwendet, um einen asynchronen Aufruf zum Abrufen von Daten durchzuführen. Ich schreibe Tests dafür, aber ich kann nicht testen, ob die Funktion aufgerufen wird, und wenn dies der Fall ist, wird sie aufgerufen, bevor die Komponente bereitgestellt wird. Sie sind wichtige Fälle, die abgedeckt werden müssen.Wie componentWillMount in einer verbundenen React-Redux-Komponente testen?

Der Code für die Smart-Komponente ist wie folgt:

const mapStateToProps = (state) => { const context = state.context; return { 
    isError: context.error, }; }; 

const options = { componentWillMount: (props) => { 
    const { dispatch } = props; 
    dispatch(fetchContextUser()); }, }; 

export function App(props) { return (
    <div className="app"> 
     { props.isError ? (<ContextError />) : (<Main />) } 
     { props.children } 
    </div> ); } 

App.propTypes = { children: PropTypes.object, // eslint-disable-line react/forbid-prop-types isError: PropTypes.bool.isRequired, // eslint-disable-line react/forbid-prop-types }; 

export default connect(mapStateToProps, null)(functional(App, options)); 

I Enzym, Chai und anderen Mock-Adapter zum Testen dieser Komponente verwenden. Der Testblock folgt:

describe.only('Render Connected Component',() => { let store; beforeEach(() => { 
    store = mockStore({ 
     context: { 
     error: false, 
     }, 
    }); }); it('Should render connected components',() => { 
    const connectedWrapper = mount(
     <Provider store={store}> 
     <ConnectedApp /> 
     </Provider> 
    ); 
    expect(connectedWrapper).to.be.present(); }); }); 

Ich möchte nur zwei Dinge prüfen:

1.) fetchContextUser 2. genannt wird) fetchContextUser aufgerufen wird, bevor das Bauteil montiert wird

Antwort

0

denke ich @ pedro-Jiminez ist schließen, aber fehlt zwei Elemente hier:

  • um in invoke componentWillMount in Enzym, müssen Sie mount verwenden, nicht shallow
  • Diese Antwort setzt voraus, dass fetchContextUser eine Stütze ist und durch einen Spion ersetzt werden kann. In diesem Fall möchten Sie wahrscheinlich in Ihrem Test store.dispatch stub und behaupten, dass es mit fetchContextUser aufgerufen wurde, vorausgesetzt, das ist nur eine reine Funktion.

So der Test würde wie folgt aussehen:

describe.only('Render Connected Component',() => { 
    let store; 
    beforeEach(() => { 
    store = mockStore({ 
     context: { 
     error: false, 
     }, 
    }); 
    // stub dispatch 
    sinon.stub(store.dispatch); 
    }); 
    it('Should render connected components',() => { 
    const connectedWrapper = mount(
     <Provider store={store}> 
     <ConnectedApp /> 
     </Provider> 
    ); 
    expect(connectedWrapper).to.be.present(); 
    // Now test dispatch called 
    expect(store.dispatch.calledOnce).to.be.true; 
    expect(store.dispatch.args[0][0]).to.deepEqual(fetchContextUser()); 
    }); 
}); 
0

Ich denke, dass Sie nur testen müssen, dass die componentWillMount-Methode die fetchContextUser Aktion aufruft, weil Sie darauf vertrauen müssen, dass ReactJS den Aufruf aufrufen wird componentWillMount Methode, bevor es montiert wird, so dass Prämisse Ihren zweiten Fall testen. So, den ersten Fall zu testen, ich glaube, Sie so etwas tun kann:

import sinon from 'sinon'; 
... 

it('It calls fetchContextUser when calls componentWillMount',() => { 
    const fetchContextUserSpy = sinon.spy(); 
    const wrapper = shallow(<App fetchContextUser={fetchContextUserSpy} />); 
    fetchContextUserSpy.reset(); //reset the spy to avoid unwanted calls 
    wrapper.instance().componentWillMount(); // Call componentWillMount directly 
    expect(fetchContextUserSpy.calledOnce).to.be.true; // Expect that after call componentWillMount() the fetchContextUserSpy was called once 

In diesem Test, der Sie direkt die componentWillMount() Funktion rufen Sie einfach und erwartet, dass der fetchContextUserSpy genannt wird, so dass der Test Ihres Fall 1. Ich verwende sinon.js, um zu testen, wenn eine Funktion aufgerufen wird.

Wieder Ihre Fall 2 nicht benötigt getestet werden, weil ReactJS garantiert, dass die componentWillMount Methode aufgerufen wird, bevor das Bauteil montiert ist.

============================================== ===========================

Versuchen Sie, diese mit funktionalen Komponente

it('It calls fetchContextUser when mounted',() => { 
    const fetchContextUserSpy = sinon.spy(); 
    const wrapper = shallow(<App fetchContextUser={fetchContextUserSpy} />); 
    expect(fetchContextUserSpy.calledOnce).to.be.true; // Expect that the component calls the fetchContextUserSpy 
}); 
+0

Auch ich erhalte eine Fehlermeldung, die ** wrapper.instance (...) componentWillMount ist keine Funktion. **. –

+0

Das kann passieren, weil Ihre Komponente eine ** funktionale Komponente ** ist und diese Art von Komponenten nicht auf ** componentWillMount ** oder irgendeine ** Lebenszyklusmethode ** zugreifen kann. –

+0

Ja, es ist eine funktionale Komponente. Gibt es eine Chance dafür? –

Verwandte Themen