我如何为 useEffect 和 dispatch 中未覆盖的行编写测试?

How could I write tests for uncovered lines in useEffect and dispatch?

最近开始写测试,不太熟悉

当我 运行 :

$ yarn test:coverage

我面对这个结果:

我想在我的下拉列表发生变化时通过调度获取模型列表 (formik.values.make),并且当用户 select 模型时,获取装饰列表。

如何为这两行编写测试:

useEffect(() => {
    if (formik.values.make) {
      dispatch(carModelsSuccess(formik.values.make));// <-- 59 line ***
    }
    if (formik.values.model) {
      dispatch(carTrimsSuccess(formik.values.model));// <--- 62 line ***
    }
}, [dispatch, formik.values.make, formik.values.model])

这部分:

<FormControl className={classes.formControl} disabled={!formik.values.model}>
    <InputLabel id="trim">Trim</InputLabel>
    <Select
        data-testid="trim"
        labelId="trim"
        id="trim"
        name="trim"
        value={formik.values.trim}
        onChange={formik.handleChange}
    >
        {carTrims?.map(({ name, value }) => (
          <MenuItem value={value} key={value}>{name}</MenuItem>
        ))}
    </Select>
</FormControl>

我和 Next.js 一起工作,我想用 Jest 和@testing-library/react 编写测试。我还使用 material-UI 作为 select 选项。 我在 google 中搜索了很多有关如何为此代码编写测试的内容,但我找不到任何东西。

useEffect 将在渲染本身上调用,您只需要使用所需的相应道具进行渲染即可。

假设您的代码位于一个名为 TestComponent 的组件中,该组件将 formik 作为 props,请参见下面的代码

const props = {
    formik: {
        values: {
          make: 'Japan' // a truthy value,
          model: 2010 // a truthy value
        }
    },
   dispatch: Jest.fn()
}
const {getByTestId} = render(<TestComponent {...props} />);

这将为您覆盖这些线路。

我成功编写了测试: 添加 inputProps={{ id: "trimInput" }} 到 select 标签如下:

<Select
  inputProps={{
    id: "trimInput"
   }}
  data-testid="trim"
  labelId="trim"
  id="trim"
  name="trim"
  value={formik.values.trim}
  onChange={formik.handleChange}
 >
  {carTrims?.map(({ name, value }) => (
    <MenuItem value={value} key={value}>{name}</MenuItem>
 ))}
这是测试:
describe('fetch form options', () => {
  it('dispatches the actions', async () => {
    const { container } = render(<Provider store={store}><FormSection /></Provider>);
    store.dispatch = jest.fn();
    await act(async () => {
      let makeSelectInput = container.querySelector(
        "#makeInput"
      ) as HTMLDivElement;
      fireEvent.change(makeSelectInput, { target: { value: "bmw" } });
    });
    expect(store.dispatch).toBeCalledWith(carModelsSuccess('bmw'));
    await act(async () => {
      let modelSelectInput = container.querySelector(
        "#modelInput"
      ) as HTMLDivElement;
      fireEvent.change(modelSelectInput, { target: { value: "320i" } });
    });
    expect(store.dispatch).toBeCalledWith(carTrimsSuccess('320i'));
  });
});