2016-11-15 34 views
1

我有以下智能組件使用componentWillMount生命週期方法進行異步調用來獲取數據。我正在爲它編寫測試,但我無法測試該函數是否被調用,以及它是否在組件被裝載之前被調用。它們是重要的案例。如何在已連接的React-Redux組件中測試componentWillMount?

爲智能型組件的代碼如下:

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

我使用的酶,柴等模擬適配器,用於測試該組件。測試塊如下:

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

我只是想測試兩件事情:

1)fetchContextUser被稱爲 2)fetchContextUser被稱爲組件被安裝之前

回答

0

我覺得@佩德羅 - jiminez是接近,但在這裏失去了兩個元素:在酶

  • 爲了在調用componentWillMount,你需要使用mount,不shallow
  • 這個回答假定fetchContextUser是一個道具,可以用間諜來代替。在這種情況下,您可能希望在測試中存在store.dispatch,並斷言它是使用fetchContextUser調用的,假設這只是一個純函數。

所以測試會是什麼樣子:

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

我認爲你只需要測試componentWillMount方法調用fetchContextUser的動作,因爲你必須相信ReactJS會調用componentWillMount方法在安裝之前,所以,這個前提測試你的第二種情況。 因此,爲了測試我覺得你可以做這樣的事情在第一種情況:

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 

在這個測試中,你只需要直接調用componentWillMount()函數,並預計,fetchContextUserSpy被調用,從而使測試你的情況1。 我使用sinon.js來測試何時調用函數。

再次您殼體2不需要進行測試,因爲ReactJS保證了部件安裝前的componentWillMount方法被調用。

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

與功能組件試試這個

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

另外,我得到一個錯誤,** wrapper.instance(...)componentWillMount不是一個函數**。 –

+0

這可能是因爲你的組件是一個**功能組件**,並且這種組件不能訪問** componentWillMount **或任何**生命週期方法**。 –

+0

是的,它是一個功能組件。有沒有機會解決這個問題? –