I am trying out immer.js in a react app and am having trouble working out how to cover the setters in my tests.
I have a parent component where my state variable is defined with useImmer like so
const [searchSubInfo, setSearchSubInfo] = useImmer(INITIAL_STATE);
INITIAL_STATE looks similar to this
const NOTIFICATION_INITIAL_STATE = {
notificationOption: {
type: 'dropdown',
value: DEFAULT_DROPDOWN_VALUE,
label: 'Submitter Notification Option',
options: submitterNotificationOpts,
status: null,
},
internalAlertEmailAddress: {
type: 'input',
value: EMPTY_STRING,
label: 'Internet Alert Email Address',
status: null,
},
...
}
In my child component I loop through all of the fields in searchSubInfo and build them. I also have one handleChange function I am trying to test.
export function SearchSubmitterInformation({
searchSubInfo,
setSearchSubInfo,
}) {
const handleChange = useCallback((e, fieldName) => {
const valueToUpdateWith = e.target.value;
setSearchSubInfo((draft) => {
draft[fieldName].status = validateTextFields(valueToUpdateWith);
draft[fieldName].value = valueToUpdateWith;
});
}, []);
let startIndex = 0;
return (
<div id="submitter-info" className={styles.searchViewContainer}>
{
searchSubInfo.groupConfig.map((group) => {
const groupTotal = group.groupLength;
const endIndex = startIndex + Number(groupTotal);
const { subHeading } = group;
const allKeys = Object.keys(searchSubInfo);
const fieldKeys = allKeys.slice(startIndex, endIndex);
startIndex += groupTotal;
return (
<div
key={subHeading}
className={styles.subGroup}
>
<h2 className={styles.subGroupHeading}>{subHeading}</h2>
<ConnectedFieldGenerator
fieldKeys={fieldKeys}
handleChange={handleChange}
state={searchSubInfo}
/>
</div>
);
})
}
</div>
);
}
This is my test case, which is passing.
export async function selectDropdownValue(container, selector, option) {
const element = container.querySelector(selector);
await userEvent.selectOptions(element, [option]);
expect(element).toHaveValue(option);
}
const props = {
searchSubInfo: mockState,
setSearchSubInfo: jest.fn(),
};
describe('SearchSubmitterInformation', () => {
it('select dropdown values', async () => {
await act(async () => {
const { container } = render(<SearchSubmitterInformation {...props} />);
const element = container.querySelector('#submitterRoleType-dropdown');
expect(element).toBeVisible();
await act(async () => {
await selectDropdownValue(container, '#submitterRoleType-dropdown', '001');
});
});
});
However, the coverage report is showing these lines as not covered, and I am confused how I cover them.