I am struggling to cover the setter function of useImmer in my react application that uses immer.js

90 Views Asked by At

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.

uncovered test lines

0

There are 0 best solutions below