我正在使用 Jest 0.4.0。我有一个组件(来自 react-router 文档):
var stubRouterContext = (Component, props, stubs) => {
function RouterStub() { }
Object.assign(RouterStub, {
makePath () {},
makeHref () {},
transitionTo () {},
replaceWith () {},
goBack () {},
getCurrentPath () {},
getCurrentRoutes () {},
getCurrentPathname () {},
getCurrentParams () {},
getCurrentQuery () {},
isActive () {},
getRouteAtDepth() {},
setRouteComponentAtDepth() {}
}, stubs)
return React.createClass({
childContextTypes: {
router: React.PropTypes.func,
routeDepth: React.PropTypes.number
},
getChildContext () {
return {
router: RouterStub,
routeDepth: 0
};
},
render () {
return <Component {...props} />
}
});
};
我的组件使用componentWillUpdate
:
getInitialState: function(){
return {something: ""};
},
componentWillUpdate: function(nextProps, nextState) {
if(nextState.something === "12345"){
this.context.router.transitionTo("MyRoute", {id: nextState.something});
}
},
在我的测试中:
var ComponentWrapper = stubRouterContext(MyComponent, {});
var myComponentInstance = TestUtils.renderIntoDocument(<ComponentWrapper />);
it('expects to do something on componentWillUpdate', function(){
myComponentInstance.setState({something: "12345"});
expect(myComponentInstance.getChildContext().router.transitionTo.mock.calls[0][0]).toEqual('MyRoute');
expect(myComponentInstance.getChildContext().router.transitionTo.mock.calls[0][1]).toEqual({id: '12345'});
});
像我打电话setState
,我nextState
的componentWillUpdate
永远是something: ""
。但是,在测试中,如果我检查的内容myComponentInstance.state
是something: "12345"
. 所以基本上,componentWillUpdate
被调用但没有新状态,即使我的实例组件有它。
对此有何想法?
——
编辑 1
以下建议基于 setState 是异步函数,但这并没有解决问题。我还试图以这种方式模拟商店变化(Flux 模式):
myStore.getState = jest.genMockFunction().mockImplementation(function() {
return{
something: "12345",
};
});
myComponentInstance.onChange(); //Simulate store change (this function has setState inside taking values from the store)
好吧,那也没有用,实际上是在告诉我onChange
未定义。所以我的问题是 react-router 包装器。我找到了一个解决方案,但我不确定是否有更好的解决方案,因为这个看起来很hacky。它是以下内容:
var RouterWrapper = stubRouterContext(Component, {ref: "myRealComponentInstance"});
var renderedComponent = TestUtils.renderIntoDocument(<RouterWrapper />);
var myComponentInstance = renderedComponent.refs.myRealComponentInstance;
这样,无论是myComponentInstance.setState
模拟还是模拟myComponentInstance.onChange
存储都可以工作,我不需要使用异步函数。