How can I use Jest to spy on a method call?

前端 未结 4 1549
醉梦人生
醉梦人生 2020-12-01 01:08

I recently wanted to test that some custom method gets conditionally called in the componentDidMount method of a React component.

componentDidMo         


        
相关标签:
4条回答
  • 2020-12-01 01:43

    If you're trying to test public methods being called on componentDidMount (if you're using TypeScript), you'll need to explicitly call the instance's componentDidMount method call, since the public methods aren't defined until after the component is instantiated.

    To test something like this:

    Code

    public componentDidMount() {
      if (this.props.initOpen) {
        this.methodName();
      }
    }
    
    public methodName = () => {
      // some code here
    }
    

    Test

    it('should call methodName during componentDidMount', () => {
      const wrapper = mount(<MyComponent {...props} />);
      const instance = wrapper.instance();
      jest.spyOn(instance, 'methodName')
      expect(instance.methodName).toHaveBeenCalled();
    });
    
    0 讨论(0)
  • 2020-12-01 01:52

    I know its a bit late, but I came across this and would suggest that to test componentDidMount initiates the call to your nested method that your test should look something like:

    Module

    componentDidMount() {
      if (this.props.initOpen) {
        this.methodName();
      }
    }
    

    Test - Good

    it('should call methodName during componentDidMount', () => {
        const methodNameFake = jest.spyOn(MyComponent.prototype, 'methodName');
        const wrapper = mount(<MyComponent {...props} />);
        expect(methodNameFake).toHaveBeenCalledTimes(1);
    });
    

    If you call componentDidMount then the assertion that methodName was called via componentDidMount is more valid.

    Test - Bad

    it('should call methodName during componentDidMount', () => {
        const spy = jest.spyOn(Component.prototype, 'methodName');
        const wrapper = mount(<Component {...props} />);
        wrapper.instance().methodName();
        expect(spy).toHaveBeenCalled();
    }
    

    By writing the test like this - you call the method and then assert that it was called. Which of course it will have given you just called it.

    0 讨论(0)
  • 2020-12-01 02:00

    The key is using jests spyOn method on the object's prototype. It should be like this:

    const spy = jest.spyOn(Component.prototype, 'methodName');
    const wrapper = mount(<Component {...props} />);
    wrapper.instance().methodName();
    expect(spy).toHaveBeenCalled();
    

    As found here e.g.: Test if function is called react and enzyme

    Please note it is also best practice to clear the spied function after each test run

    let spy
    
    afterEach(() => {
      spy.mockClear()
    })
    

    https://facebook.github.io/jest/docs/en/jest-object.html#jestclearallmocks

    0 讨论(0)
  • 2020-12-01 02:05
    const toastMethodSpy = jest.spyOn(sharedMockedOTPComponent, 'toast')
    sharedMockedOTPComponent.handleResendOtpFailure(networkError)
    
    //hide loader
    expect(sharedMockedOTPComponent.state.showLoader).toBe(false)
    //error message in toast should have been shown
    expect(toastMethodSpy).toHaveBeenCalledTimes(1)
    
    0 讨论(0)
提交回复
热议问题