Why is my code not reflected properly during rendering for unit test

27 Views Asked by At

I have this test

describe('Effective Date', () => {
  test('User select or key in valid date', async () => {
    debug();
    const effectiveDate = screen.getByTestId('effectiveDateinput');
    await act(async () => {
      await userEvent.type(effectiveDate, '01/01/2023');
    });
    expect(effectiveDate).toHaveValue('01/01/2023');
  });
})

Which I am testing for the correct input

const handleEffectiveDateOnChange = date => {
  if (date === null || date === undefined) {
    setErrors(prevErrors => ({
      ...prevErrors,
      effectiveDate: 'Please fill in the field above',
    }));
  } else if (!validateDateFormat(date)) {
    setErrors(prevErrors => ({
      ...prevErrors,
      effectiveDate: 'Please enter the date in DD/MM/YYYY format',
    }));
  } else {
    setErrors(prevErrors => ({
      ...prevErrors,
      effectiveDate: '',
    }));

    setEffectiveDate(date);
  }
};

It says TestingLibraryElementError: Unable to find an element by: [data-testid="effectiveDateinput"]

But when I go back to my page to check, I have this data-testid="effectiveDateinput" for my Effective Date

<div className="col-md-3">
  <label className={`user-details-label`} htmlFor="effectiveDate">
    Effective Date<span style={{ color: 'red' }}>*</span>
  </label>

  <LocalizationProvider dateAdapter={AdapterMoment}>
    <DatePicker
      format="DD/MM/YYYY"
      onChange={date => handleEffectiveDateOnChange(date)}
      value={effectiveDate}
      data-testid="effectiveDateinput"
      sx={{
        width: '100%',
        '& .MuiInputBase-input': {
          padding: '6px 12px',
        },
        '& .MuiInputBase-root': {
          borderRadius: 'var(--bs-border-radius)',
          color: 'var(--bs-body-color)',
        },
      }}
      slotProps={{
        textField: {
          id: 'expiryDate',
          variant: 'standard',
        },
      }}
    />
    {errors.effectiveDate && <ErrorBar errorMsg={errors.effectiveDate} />}
  </LocalizationProvider>
</div>

I tried using await for const effectiveDate = await screen.getByTestId('effectiveDateinput'); but also same issue.

Am I testing this wrongly?

1

There are 1 best solutions below

0
Drew Reese On

According to this GitHug issue it seems not all extraneous props are passed through to the actual DOM elements. The "fix" is to use a custom input (customInput prop) and pass through all the other props, then specify the data-x (and any other) attribute(s).

Example:

const CustomInput = React.forwardRef((props, ref) => (
  <input ref={ref} type="text" {...props} />
));
<DatePicker
  format="DD/MM/YYYY"
  onChange={handleEffectiveDateOnChange}
  value={effectiveDate}
  customInput={<CustomInput data-testid="effectiveDateinput" />} // <--
  sx={{
    width: '100%',
    '& .MuiInputBase-input': {
      padding: '6px 12px',
    },
    '& .MuiInputBase-root': {
      borderRadius: 'var(--bs-border-radius)',
      color: 'var(--bs-body-color)',
    },
  }}
  slotProps={{
    textField: {
      id: 'expiryDate',
      variant: 'standard',
    },
  }}
/>