无法解决反应测试中未包装的行为错误



我在功能组件中使用fetch,所以我当然也有状态更新。在测试中,我使用模拟提取,它返回我自己的假数据。这是我的3个测试用例:

  1. 检查是否调用了fetch(只有一个expect包装在waitfor中(
  2. 检查数据是否正确显示(检查是否显示了假数据,它包装在waitfor中(
  3. 检查点击元素后是否指向假url(它有一个元素的userEvent.click,然后检查新url,它也是fetch返回的假数据的一部分。它被包装在waitfor中(

即使我使用了waitfor,并且所有的3个测试都通过了,我仍然有3个未包装的行为错误。可能是什么问题?

更新:这是第三个测试代码作为的例子

const savedLocation = window.location;
jest.spyOn(window, 'fetch');
const fakeData = { "articles" : [{
title: "title",
url: "url",
desc: "desc"
}]};
beforeEach(() => {
delete window.location;
window.location = { assign: jest.fn() };
window.fetch.mockResolvedValueOnce({ json: () => fakeData });
render(<Router><Home /></Router>);
});
afterEach(() => {
window.location = savedLocation;
});
it("fetch is called", async () => {
await waitFor(() => {
expect(window.fetch).toHaveBeenCalledTimes(1);
});
});
it("article is displayed with correct data", async () => {
await waitFor(() => {
expect(screen.getByRole('heading')).toHaveTextContent('title');
expect(screen.getByTestId('desc')).toHaveTextContent('desc');
});
});
it("click on article calls window.location.assign with fake url", async () => {
await waitFor(() => {
userEvent.click(screen.getByTestId('artCont'));
expect(window.location.assign).toHaveBeenCalledWith(fakeData.articles[0].url);
});
});

请注意,artCont是div容器,其中显示所获取数据的标题和描述。单击该div将更改url。此外,我删除了window.location,以便能够检查assign函数,因为它在新版本中不能再被嘲笑了,但我不知道它是否与我收到的3个错误有关。

我也遇到了类似的问题,这是在引入异步状态更新后出现的(我使用的是redux和RTK(。

render封装在act中为我修复了此问题。

我不确定这是解决方案,也不确定这是否是一个好方法,但它需要大量的挖掘,WFM,这是我本可以更早使用的信息,所以我会分享它:

await act(() =>
render(
<Provider store={store}>
<ItemList />
</Provider>
)
);
// At this point all state changes have finished rendering,
// including async ones triggered during rendering itself.
// Speculation: Without act(), the Promises would resolve outside
// the original render(), triggering state and DOM changes,
// and that causes the error messages.
expect(screen.getByRole('heading')).toHaveTextContent('title');

这样,我也不需要使用任何waitForawait findBy..魔术(搜索此问题时的常见建议(:普通getBy..现在总是有效的。

我还需要在act中封装redux调度,因为它们也会触发DOM更改:

await act(() => store.dispatch(itemSelected(itemKey)));

如果有人能纠正我,更好地解释,或证实这一点,我将不胜感激。

最新更新