Reputation: 4087
At first, I thought there was something wrong with other aspects of my code. So I created a new, simplified version of the component in a newly created project and wrote the test for it but my spy is still not being called.
Here's the component I'm testing:
import React from 'react';
class TextEditor extends React.Component {
handleChange = (e) => {
console.log({ value: e.target.value });
}
render() {
return (
<div>
<input type="text" name="name" id="name" onChange={this.handleChange} />
</div>
);
}
}
export default TextEditor;
And here is the unit test:
import React from 'react';
import { shallow } from 'enzyme';
import TextEditor from '../TextEditor';
describe('TextEditor', () => {
it('handles change event', () => {
const wrapper = shallow(<TextEditor />);
const spy = jest.spyOn(wrapper.instance(), 'handleChange');
wrapper.find('input').simulate('change', { target: { value: 'test value' }});
expect(spy).toHaveBeenCalledTimes(1);
});
});
The result of running the test:
When I run this, it fails because the spy doesn't get called. But notice that the console.log statement in the handleChange function gets executed. So the test actually calls the function but the spy isn't recognized as having been called.
What could I be doing wrong? Thanks for your ideas.
Upvotes: 0
Views: 665
Reputation: 102617
The handleChange
method is class properties, not the instance method of the class.
If you insist to use class properties, you should call wrapper.instance().forceUpdate()
after spying. See issue#365
E.g.
TextEditor.tsx
:
import React from 'react';
class TextEditor extends React.Component {
handleChange = (e) => {
console.log({ value: e.target.value });
};
render() {
return (
<div>
<input type="text" name="name" id="name" onChange={this.handleChange} />
</div>
);
}
}
export default TextEditor;
TextEditor.test.tsx
:
import { shallow } from 'enzyme';
import React from 'react';
import TextEditor from './TextEditor';
describe('TextEditor', () => {
it('handles change event', () => {
const wrapper = shallow(<TextEditor />);
const spy = jest.spyOn(wrapper.instance(), 'handleChange');
wrapper.instance().forceUpdate();
wrapper.find('input').simulate('change', { target: { value: 'test value' } });
expect(spy).toHaveBeenCalledTimes(1);
});
});
Test result:
PASS examples/70652888/TextEditor.test.tsx (13.006 s)
TextEditor
✓ handles change event (100 ms)
console.log
{ value: 'test value' }
at TextEditor.handleChange (examples/70652888/TextEditor.tsx:5:13)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 14.708 s
Also, see this answer
Upvotes: 1