I have a parent component where a piece of state is defined with useImmer like this:
const [example, setExample] = useImmer({
submitterId: {
value: EMPTY_STRING,
label: 'Submitter ID',
disabled: false,
status: null,
schema: submitterIdSchema
},
submitterName: {
value: EMPTY_STRING,
label: 'Submitter Name',
disabled: false,
status: null,
schema: submitterNameSchema
}});
These states are passed down as props to a child component which I am trying to write jest tests for. This is a simplified example.
export function ChildComponent({
example,
setExample,
}) {
const handleInputChange = async (e, fieldName) => {
const valueToUpdateWith = e.target.value;
const schema = example[fieldName].yupSchema;
const status = await validate(valueToUpdateWith, schema);
setExample((draft) => {
draft[fieldName].status = status;
draft[fieldName].value = valueToUpdateWith;
});
};
return (
<div id="exampleContainer">
<ConnectedFieldGenerator // this just loops through keys in example and generates label/input field groups for them
fieldKeys={Object.keys(example)}
handleInputChange={handleInputChange}
/>
</div>
);
}
I have written the below test in order to cover the handleInputChange function, but in my coverage report the logic inside of setExample is notcovered.
const props = {
example: EXAMPLE_INITIAL_FIELD_STATE,
setExample: jest.fn(),
};
describe('Search Table Renders', () => {
it('input change of example', async () => {
const { container } = render(<ChildComponent{...props} />);
await enterInputValue(container, '#submitterId-input', 'Submitter ID');
expect(props.setBasicSearchState).toHaveBeenCalled();
});
});
How would I cover the below lines in handleInputChange with my tests?
setExample((draft) => {
draft[fieldName].status = status; // NOT COVERED
draft[fieldName].value = valueToUpdateWith; // NOT COVERED
});
You don't need to mock the
setExample
function, create a parent component for testing purposes. Keep it as simple as possible, retaining enough logic for a single test case. Then, pass the realsetExample
function returned by theuseImmer
hook to the<ChildComponent/>
component. Finally, assert the latest state the component has rendered.E.g.
Child.jsx
:Child.test.jsx
:Test result: