redux 什么时候有必要在React测试库中使用'rerender'?

g6ll5ycj  于 2022-11-12  发布在  React
关注(0)|答案(1)|浏览(107)

在过去,我和我的同事通常会为主要的父组件编写React Testing Library(RTL)测试,这些父组件通常有许多嵌套的子组件。这种测试是有意义的,并且运行良好。顺便说一句,所讨论的子组件非常专用于父组件,而不是可重用的种类。
但是现在我们尝试为每一个组件编写RTL测试。今天我尝试为Alerts组件构建测试,它是Alert组件的父组件,从顶层组件向下大约4层。下面是我的测试文件中的一些示例代码:

function renderDom(component, store) {
  return {
    ...render(<Provider store={store}>{component}</Provider>),
    store,
  };
}

let store = configureStore(_initialState);
const spy = jest.spyOn(store, 'dispatch');
const { queryByTestId, queryByText, debug } = renderDom(
  <Alerts question={store.getState().pageBuilder.userForm.steps[0].tasks[0].questions[1]} />,
  store
);

然后,我开始编写典型的RTL代码,让Alerts组件完成它的工作。其中一个方法是单击一个按钮,这将触发一个ADD_ALERT操作。我逐步完成了所有代码,Redux reducer显然工作正常,并有一个新的警报,正如我所希望的那样,但回到Alerts组件,question.alerts仍然是null,而在生产代码中,它肯定会用新的警报进行适当更新。
我和一位同事谈过,他说对于这种类型的测试,我需要人工地重新呈现组件,如下所示:

rerender(<Provider store={store}><Alerts question={store.getState().pageBuilder.userForm.steps[0].tasks[0].questions[1]} /></Provider>);

我尝试过这个方法,它似乎是一个解决方案。我不完全理解为什么我必须这样做,我想我应该接触社区,看看是否有一种方法可以避免使用rerender

zpf6vheq

zpf6vheq1#

如果没有看到更多的代码,很难确定这一点,但我使用RTL的典型方法是接受模拟单击按钮的fireEvent调用,并将其 Package 在一个act调用中。这应该会导致React完成处理来自事件的任何事件,更新状态,重新呈现等。
或者,如果您知道特定的DOM变更应该会因为引发事件而发生,则可以使用waitForReact Testing Library intro的范例:

render(<Fetch url="/greeting" />)

  fireEvent.click(screen.getByText('Load Greeting'))

  await waitFor(() => screen.getByRole('alert'))

相关问题