2017-04-26 171 views
1

我使用jestenzyme來單元測試我的React應用程序,並且我正在測試連接組件。如何在連接的Redux組件中使用Jest單元測試Redux動作

我有一個簡單的組件,它下面的邏輯:

class LoginPage extends React.Component { 

    componentDidMount() { 
     if (!this.props.reduxReducer.appBootstrapped) { 
       this.props.dispatch(ReduxActions.fadeOutAndRemoveSplashScreen(500)); 
     } 
    } 

    render() { 
     return (
      <div data-page="login-page" > 
       <div>This is the login page.</div> 
      </div> 
     ); 
    } 
} 

const mapStateToProps = (state) => { 
    return { 
     reduxReducer: state.reduxReducer 
    } 
}; 

export default connect(mapStateToProps, null)(LoginPage); 

所以,這是顯示一個包含一些文本<div />元素的成分,但我要測試的重要組成部分,是當組件已安裝,將調度一項操作以隱藏啓動畫面。 我只想在應用程序未被引導時發生這種情況。

我有一個簡單的單元測試,以測試該組件呈現:

describe("[LoginPage Component]",() => { 
    it("Renders without a problem.",() => { 
     // Act. 
     const wrapper = mount(
      <LoginPage store={ reduxStore } /> 
     ); 

     // Assert. 
     expect(wrapper.find("div[data-page=\"login-page\"]").length).toBe(1); 
    }); 
}); 

reduxStore屬性是我的實際終極版店,用下面的代碼創建:

const reduxStore = createStore(
    combineReducers(
     { 
      reduxReducer 
     } 
    ) 
); 

現在,我怎樣才能測試componentDidMount()方法,以及更多的特殊情況,測試還原動作fadeOutAndRemoveSplashScreen()僅在應用程序尚未引導時調用。

我確實認爲我需要嘲笑我的redux商店,但是,我是一個新手,並且現在不要如何開始,因此我將非常感謝您的示例。

如果對我的實現有任何其他想法,請隨時提供一些建議。

親切的問候

回答

3

我不會用原始dispatch方法發送關閉動作。我會用mapDispatchToProps。這使得你的動作直接在組件道具中可用 - 在這裏我們使用ES6解構爲connect方法中的簡短手段。

然後,而不是嘲笑redux商店,我只是測試你的組件沒有它。嘗試將輸出添加到您的class(第一行)。例如:

export class LoginPage extends React.Component { 

    componentDidMount() { 
     if (!this.props.reduxReducer.appBootstrapped) { 
      // make sure that you are using this.props.action() not 
      // just the action(), which is not connected to redux 
      this.props.fadeOutAndRemoveSplashScreen(500); 
     } 
    } 

    render() { 
     return (
      <div data-page="login-page" > 
       <div>This is the login page.</div> 
      </div> 
     ); 
    } 
} 

const mapStateToProps = (state) => { 
    return { 
     reduxReducer: state.reduxReducer 
    } 
}; 

export default connect(mapStateToProps, { 
    fadeOutAndRemoveSplashScreen: ReduxActions.fadeOutAndRemoveSplashScreen 
})(LoginPage); 

然後在您的測試,而不是導入連接的組件,導入類:

import ConnectedLoginPage, { LoginPage } from '/path/to/component'; 

然後簡單地傳遞任何道具,你想測試LoginPage。因此,我們將設置你的appBooststrapped爲false,然後通過這一行動sinon間諜:

const spy = sinon.spy(); 
const reduxReducer = { 
    appBootstrapped: false, // or true 
} 
const wrapper = mount(
    <LoginPage reduxReducer={reduxReducer} fadeOutAndRemoveSplashScreen={spy} /> 
); 

// test that the spy was called 
expect(spy.callCount).to.equal(1); 

它使測試更簡單,更重要的是要測試的組件行爲 - 不是終極版。

+0

謝謝,exactely我正在尋找的答案。 – Complexity

相關問題