I am attempting to test whether a React component method is called using enzyme and jest. The function is supposed to be called when a <section>
element becomes unfocused (on blur). The component is connected to a Redux store, but it is also exported by name, to take Redux out of the equation. Below is a simplified version of the component:
export class Section extends React.Component {
constructor(props) {
super(props)
this.formRef = React.createRef();
this.submitForm = this.submitForm.bind(this);
this.state = {
formSubmitted: false
}
}
submitForm() {
console.log("form submitted");
this.setState({ formSubmitted: true })
if (this.formRef && this.formRef.current) {
this.formRef.current.submit();
}
}
render() {
return (
<section onBlur={this.submitForm}>
<form ref={this.formRef} action={url} method='post'>
<input type="text" name="something" />
</form>
</section>
);
}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(Section);
I have tried all kinds of combinations for the spyOn
portion, since it seems to be the root of the issue. All have failed.
import React from 'react';
import { shallow } from 'enzyme';
import { Section } from './Section';
describe('Section', () => {
it('should submit form on blur', () => {
const wrapper = shallow(<Section content={{ body: [] }} />);
const spy = spyOn(wrapper.instance(), 'submitForm');
const spy2 = spyOn(Section.prototype, 'submitForm');
const spy3 = jest.spyOn(wrapper.instance(), 'submitForm');
const spy4 = jest.spyOn(Section.prototype, 'submitForm');
wrapper.find('section').simulate('blur');
expect(wrapper.state().formSubmitted).toEqual(true);
expect(spy).toHaveBeenCalled();
expect(spy2).toHaveBeenCalled();
expect(spy3).toHaveBeenCalled();
expect(spy4).toHaveBeenCalled();
})
})
I gave the component a state and tested it in addition to testing expect(...).toHaveBeenCalled
in order to verify whether the function was actually called, and it seems to be the case.
The console.log('form submitted')
appears in the console.
The test expect(wrapper.state().formSubmitted).toEqual(true);
passes, which indicates to me that the correct function is being called. However, I don't want to have an unnecessary state just for the test. The state has just been added to assert that "submitForm" method is being called.
The assertions expect(...).toHaveBeenCalled()
all fail with error Expected spy to have been called, but it was not called
or Expected mock function to have been called, but it was not called.