I am working on a test that checks that a React input component's onChange
handler is called. I am using React 17, the react-testing-library, and jest.
const Input = ({ value, onChange }) => {
return <input type="text" value={value} onChange={onChange} />;
};
test("calling onChange works", () => {
const value = "default value";
const handleChange = jest.fn();
handleChange.mockImplementation((e) =>
console.log("value is correct here", e.target.value)
);
const { container } = render(<Input value={value} onChange={handleChange} />);
const input = container.querySelector("input");
fireEvent.change(input, { target: { value: "new value" } });
// works
expect(handleChange).toHaveBeenCalled();
/// does not work
expect(handleChange).toHaveBeenCalledWith(
expect.objectContaining({
target: expect.objectContaining({
value: "new value"
})
})
);
});
The first assertion, checking that the handler was called, works, but I am not able to assert that the event properly contains the new value. Interestingly, mocking the implementation shows that the correct value is being passed.
https://codesandbox.io/s/jest-testing-react-forked-7gytg?file=/src/components/Input.test.js:116-763
I am aware that it would be easier to test the parent form component, seeing if the new input is displayed; however, I would like to unit test this individual component if possible.
I think it's ok to put your assertion(s) in the mock implementation. I have something similar, testing a checkbox component.
it('should raise on onChange event when there is a state change', () => {
let spy = jest.fn();
spy.mockImplementation((e) => {
expect(e.target.checked).toBe(true);
expect(e.target.value).toBe('foo');
})
render(<Checkbox value={'foo'} checked={false} onChange={spy} />);
userEvent.click(screen.getByRole('checkbox'));
expect(spy).toHaveBeenCalledTimes(1);
});
If you put in an assertion that you know will fail and see the test fail, you know they're getting hit.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With