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?
4 Answers
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) }); }) 0There is the spyOn method, that was introduced with v19 some days ago, that does exactly what you are looking for
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(); }); 1I'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"