I recently wanted to test that some custom method gets conditionally called in the componentDidMount
method of a React component.
componentDidMo
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();
});
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.
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
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)