Munsterberg
Munsterberg

Reputation: 828

Jest spy on functionality

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?

Upvotes: 67

Views: 196639

Answers (4)

Denis Rybalka
Denis Rybalka

Reputation: 1871

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)
  });
})

Upvotes: 76

Wallysson Nunes
Wallysson Nunes

Reputation: 750

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"

Upvotes: 6

Andreas K&#246;berle
Andreas K&#246;berle

Reputation: 110922

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

Upvotes: 22

Nahush Farkande
Nahush Farkande

Reputation: 5646

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();
});

Upvotes: 17

Related Questions