在过去,我和我的同事通常会为主要的父组件编写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
。
1条答案
按热度按时间zpf6vheq1#
如果没有看到更多的代码,很难确定这一点,但我使用RTL的典型方法是接受模拟单击按钮的
fireEvent
调用,并将其 Package 在一个act调用中。这应该会导致React完成处理来自事件的任何事件,更新状态,重新呈现等。或者,如果您知道特定的DOM变更应该会因为引发事件而发生,则可以使用
waitFor
。React Testing Library intro的范例: