lundi 27 février 2017

Sinon stub instance method declared in mapDispatchToProps

New to testing and React Redux, so I may be conflating a few issues here. I will only present one example, but I have tried many different combinations of mount(), shallow(), instance(), stub, spy and more.

Given a component, where setFooData() updates redux state and Foo.props.data:

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

...

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

I would like to write some tests around the conditions under which setFooData() is called, namely conditions in lifecycle methods like componentDidMount() and componentWillReceiveProps().

Because setFooData() involves server calls and more, and because these tests merely concern the view layer and how the component renders as a result of Foo.props.data being set eventually by setFooData(), setFooData() seems like a good candidate for stub.

Therefore, Enzyme's shallow(), rather than mount(), seems appropriate, correct? In any case, when I try to stub setFooData():

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

I receive the error:

Attempted to wrap undefined property setFooData as function

Upon inspection, wrapper.instance() yields an object where setFooData() is indeed not defined, but according to other examples, I would think it should be.

Furthermore, setFooData() does exist on wrapper.instance().selector.props, and while let stub = sinon.stub(wrapper.instance().selector.props, 'setFooData'); avoids the error, when I inspect the object setFooData() =/= stub, and the function is not called as per the test.

When I use mount() instead,

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

I receive a different error that appears related to the body of setFooData(), so setFooData() is called but the function is not actually stubbed to prevent its real body from being executed.

Thanks for any help to clarify my understanding.

Aucun commentaire:

Enregistrer un commentaire