在mapDispatchToProps中声明的Sinon存根实例方法

时间:2017-02-28 04:22:39

标签: unit-testing testing react-redux sinon enzyme

新测试和React Redux,所以我可能会在这里混淆一​​些问题。我只会提供一个示例,但我尝试了mount()shallow()instance()stubspy等多种不同的组合。

给定一个组件,其中setFooData()更新redux状态和Foo.props.data

const mapDispatchToProps = (dispatch, props) => ({
    setFooData(fooId, data) {
        dispatch(Actions.setFooData(fooId, data));
    },
});

...

return (
        <div fooId={this.props.fooId}>
            <Foo {...fooProps}/>
        </div>
    );

我想围绕调用setFooData()的条件编写一些测试,即componentDidMount()componentWillReceiveProps()等生命周期方法中的条件。

因为setFooData()涉及服务器调用等等,并且因为这些测试仅涉及视图层以及Foo.props.data最终由setFooData() setFooData()设置而导致组件呈现的方式,{{ 1}}似乎是stub的好候选人。

因此,酶shallow()而不是mount()似乎合适,对吗?在任何情况下,当我尝试stub setFooData()时:

let wrapper = return shallow(<Foo {...props}/>);
let stub = sinon.stub(wrapper.instance(), 'setFooData');

我收到错误:

Attempted to wrap undefined property setFooData as function

经过检查,wrapper.instance()会产生一个确实没有定义setFooData()的对象,但根据其他例子,我认为应该是这样。

此外,setFooData()确实存在wrapper.instance().selector.props,而let stub = sinon.stub(wrapper.instance().selector.props, 'setFooData');虽然避免了错误,但当我检查对象setFooData() =/= stub时,并没有根据测试

当我使用mount()时,

let wrapper = mount(<Provider store={store}><Foo {...props}/></Provider>);

let componentDidMountSpy = sinon.spy(Foo.prototype, 'componentDidMount');
let componentWillReceivePropsSpy = sinon.spy(Foo.prototype, 'componentWillReceiveProps');

expect(componentDidMountSpy.called).to.be.true;         //passes
expect(componentWillReceivePropsSpy.called).to.be.true; //passes
expect(stub.called).to.be.true;                         //fails

我收到一个与setFooData()正文相关的错误,因此setFooData()被调用,但该函数实际上并未存根,以防止其实体被执行。

感谢您提供任何帮助以澄清我的理解。

1 个答案:

答案 0 :(得分:1)

我认为你正走最艰难的道路。您应该单独测试组件,而不是connect ed组件。如果您测试connect ed组件,那么您正在进行集成测试并进行connect确实有效的双重测试。那已经在你的react-redux中测试了。

相反,在单元测试中自行测试您的动作创建者。 然后,将组件导出为名为export而不连接,并使用连接版本的默认导出。

这样你就可以简单地导入pure-React版本并将你想要的任何东西作为道具传递,以便以后轻松断言。

如果您需要专门测试这些生命周期方法中发生的事情,可以从instance调用这些方法:

const fakeActionCreator = sinon.spy()
const subject = mount(<MyComponent doSomething={ fakeActionCreator } />)
subject.instance().componentDidMount()
assert.equal(fakeActionCreator.callCount, 1)