rob*_*ear 9 javascript reactjs redux react-testing-library
在过去,我和我的同事通常会为主父组件编写 React 测试库 (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
);
Run Code Online (Sandbox Code Playgroud)
然后我开始编写典型的 RTL 代码以使Alerts
组件完成其任务。其中之一是单击将触发ADD_ALERT
操作的按钮。我单步执行了所有代码,Redux 减速器显然在新警报下正常工作,正如我所预期的那样,但回到组件中Alerts
,它question.alerts
仍然存在null
,而在生产代码中,它肯定是在新警报下正确更新的。
我与一位同事交谈,他说对于这种类型的测试,我需要人为地重新渲染组件,如下所示:
rerender(<Provider store={store}><Alerts question={store.getState().pageBuilder.userForm.steps[0].tasks[0].questions[1]} /></Provider>);
Run Code Online (Sandbox Code Playgroud)
我尝试了这个,这似乎是一个解决方案。我不完全理解为什么我必须这样做,并认为我应该联系社区,看看是否有一种方法可以避免使用rerender
.
如果没有看到更多代码,很难确定,但我使用 RTL 的典型方法是接受fireEvent
模拟单击按钮的调用并将其包装在act调用中。这应该会导致 React 完成对事件、更新状态、重新渲染等中的任何事件的处理。
或者,如果您知道触发事件后应发生特定的 DOM 更改,则可以使用waitFor
. React 测试库介绍中的一个示例:
render(<Fetch url="/greeting" />)
fireEvent.click(screen.getByText('Load Greeting'))
await waitFor(() => screen.getByRole('alert'))
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
23674 次 |
最近记录: |