我正在使用jest
和enzyme
对我的React应用程序进行单元测试,而我正在努力测试连接的组件。
我有一个简单的组件,其中包含以下逻辑:
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
属性是我的实际redux存储,使用以下代码创建:
const reduxStore = createStore(
combineReducers(
{
reduxReducer
}
)
);
现在,我如何测试componentDidMount()
方法,以及更多特殊方法,测试redux操作fadeOutAndRemoveSplashScreen()
仅在应用程序尚未引导时调用。
我认为我需要模拟我的redux商店,但是,我是这方面的新手,现在不知道如何开始,所以一个例子将受到高度赞赏。
如果对我的实施有任何其他想法,请随时提供一些建议。
亲切的问候
答案 0 :(得分:4)
我不会使用原始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);
这使得测试变得更加简单,更重要的是,您正在测试组件行为 - 而不是Redux。