The Enzyme docs for Full DOM Rendering here contains the following example of spying on a lifecycle method with Sinon:
describe('<Foo />', () => {
it('calls componentDidMount', () => {
sinon.spy(Foo.prototype, 'componentDidMount');
const wrapper = mount(<Foo />);
expect(Foo.prototype.componentDidMount.calledOnce).to.equal(true);
});
});
What is the equivalent to this using mock functions from Jest?
I'm using Create-React-App, and would rather not include Sinon if the same can be achieved with Jest.
Here's what I'd expect the test to look like:
describe('<App />', () => {
it('calls componentDidMount', () => {
jest.fn(App.prototype, 'componentDidMount');
const wrapper = mount(<App />);
expect(App.prototype.componentDidMount.mock.calls.length).toBe(1);
});
});
In this case, App.prototype.componentDidMount
doesn't reference the same function spy as it would do with Sinon.
The Jest docs on how mock functions actually work are a bit limited. I've followed the discussion here around what jest.fn() is doing, but it seems it's not really equivalent to sinon.spy().
How can I replicate that test with Jest?
As of Jest 19, you can do this:
jest.spyOn returns a mock function with all the normally available methods such as
mockClear
,mockReset
andmockRestore
.Make sure to set up your spy before you
mount
with enzyme orcreate
with react-test-renderer so that the created instance has a reference to the mocked function being spied on.This will not work with jest this way as
jest.fn
only have a parameter for the implementation. But more important, you should not spy on the internals of the object you want to test. You should think ofFoo
as a black box where you can put some properties in and get some stuff rendered back. Then you realize that there is no need to test that internal functions ofFoo
, likecomponentDidMount
, get called. The only thing that matters is the output of the black box.But if you really want do test it anyway: