Jest spy on functionality

JavascriptReactjsJestjs

Javascript Problem Overview


I am swapping to Jest from Mocha, and I'm wondering if there is a way to spy on a React method. For example, let's say I have the following method in my component (ignore the sdk library, it just constructs a jQuery Ajax call):

getData() {
    sdk.getJSON('/someURL').done(data => {
        this.setState({data});
    });
}

Using Sinon I would test this by spying on the prototype like so:

it('should call getData', () => {
    sinon.spy(Component.prototype, 'getData');
    mount(<Component />);
    expect(Component.prototype.getData.calledOnce).to.be.true;
});

This would ensure code coverage without mocking the method. Is there similar functionality in Jest?

EDIT: Also, if this functionality doesn't exist, what is the next best strategy for testing API calls?

Javascript Solutions


Solution 1 - Javascript

Actually you can use jest.spyOn jest.spyOn

If method is called when component created use:

import { mount } from 'enzyme'; 

describe('My component', () => {
  it('should call getData', () => {
    const spy = jest.spyOn(Component.prototype, 'getData');
    mount(<Component />);
    expect(spy).toHaveBeenCalledTimes(1)
  });
})

or if you have it in your DOM and method use bind you can use:

import { shallow } from 'enzyme'; 

describe('My component', () => {
  it('should call getData', () => {
    const wrapper = shallow(<Component />);
    const instance = wrapper.instance()
    const spy = jest.spyOn(instance, 'getData');
    wrapper.find('button').simulate('click')
    expect(spy).toHaveBeenCalledTimes(1)
  });
})

Solution 2 - Javascript

There is the spyOn method, that was introduced with v19 some days ago, that does exactly what you are looking for

Solution 3 - Javascript

You could go for the new spyOn method or the following should also work fine.

it('should call getData', () => {
    Component.prototype.getData = jest.fn(Component.prototype.getData);
    expect(Component.prototype.getData).toBeCalled();
});

Solution 4 - Javascript

I'm using Jest with React 16.8 - This worked for me:

  it("lifecycle method should have been called", () => {
    jest.spyOn(RedirectingOverlay.prototype, 'componentWillUnmount');
    jest.spyOn(RedirectingOverlay.prototype, 'componentDidMount');
    const wrapper = mount(<RedirectingOverlay message="Hi There!"/>);
    expect(RedirectingOverlay.prototype.componentDidMount).toHaveBeenCalledTimes(1)
    wrapper.unmount()
    expect(RedirectingOverlay.prototype.componentWillUnmount).toHaveBeenCalledTimes(1)
  })

Also using:

  • "enzyme": "^3.6.0"
  • "jest": "23.5.0"
  • "enzyme-adapter-react-16": "^1.5.0"

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMunsterbergView Question on Stackoverflow
Solution 1 - JavascriptDenis RybalkaView Answer on Stackoverflow
Solution 2 - JavascriptAndreas KöberleView Answer on Stackoverflow
Solution 3 - JavascriptNahush FarkandeView Answer on Stackoverflow
Solution 4 - JavascriptWallysson NunesView Answer on Stackoverflow