2
votes

I'm trying to test a click on a react component uszing Enzyme + Sinon

var stub = sinon.stub(Comp.prototype, 'save', function() {  });

let wrapper = shallow(
    <Comp/>
);

wrapper.find('.btn-header').simulate('click');
sinon.assert.called(stub);

Comp.prototype.refineOnClick.restore();

My Comp component has a save function that throws an exception

save: function () {
    throw('error');
}

When I run the test, I expect no errors to be thrown and the empty function in the stub to fire - but it doesn't. The actual function inside the component is fired and not the empty stub.

2
Sorry is it not calling either your stub or your regular function or is it calling your regular function and not your stub. - Ben Hare
Yeah can you clear up if you meant that the test never calls your stub or/and doesn't call the actual save function? As in, does it throw an error but it doesn't call the stub? - ZekeDroid
@BenHare It's calling the regular function and not the stub. - NiRR
I agree with what luboskrnac says in his answer that you shouldn't fake the internal. Your save method should be called from the onclick, and in turn, it's likely going to call something that communicates externally, e.g. an action from redux. Let's call that method saveViaAjax. So you'd really want to stub saveViaAjax, and saveViaAjax is what you would pass into your component. Your component's save would call saveViaAjax. - Tyler Collier

2 Answers

1
votes

You can access (and therefore stub) functions on your enzyme wrapper by using it's instance. So to test your component's save function, you do the following:

const wrapper = shallow(<Comp />)
sinon.stub(wrapper.instance(), 'save')
wrapper.find('.btn-header').simulate('click')
expect(wrapper.instance().save).to.have.been.called

Note, I'm using sinon-chai for the .to.have.been.called syntax.

0
votes

One of the principles of unit testing is, that you shouldn't fake internals of unit under test. It just makes tests less readable and maintainable. Method save is obviously internal to Comp and thus shouldn't be faked.

It would be OK if you would pass it as parameter into that component:

var stub = sinon.stub();

let wrapper = shallow(
    <Comp onSave={stub} />
);

wrapper.find('.btn-header').simulate('click');
sinon.assert.called(stub);