javascript 使用React Testing Library的Vitest:尽管有错误,但测试之间的意外组件渲染

ppcbkaq5  于 12个月前  发布在  Java
关注(0)|答案(1)|浏览(97)

我在Vitest测试设置中遇到了一个问题,即使在使用@testing-library/react的cleanup函数进行清理之后,Catalog组件在第二个测试中意外呈现。
我有一组使用React测试库的React组件测试。这些测试旨在在BrowserRouter中呈现不同的组件。第一个测试(目录链接工作)点击“检查目录”链接(在Home组件中),它呈现Catalog组件并执行一些Assert。(Register链接起作用)再次单击主页中的“Register”链接,并AssertRegister组件中的元素。
然而,尽管在每个测试之后使用cleanup并等待其完成,第二个测试似乎继承了第一个测试中Catalog组件的状态或呈现。我已经尝试了各种方法,包括使用await cleanup()并完全删除清理,但问题仍然存在。
下面是我的测试设置:

import { afterEach, vi } from 'vitest';
import { cleanup } from '@testing-library/react';
import '@testing-library/jest-dom/vitest';

import { JSDOM } from 'jsdom';
const { window } = new JSDOM();
global.window = window;
// Mock the alert function
window.alert = vi.fn();

afterEach(() => {
  cleanup();
});

字符串
以下是测试:

it('Catalog link works', async () => {
        render(<BrowserRouter>
            <App>
                <Home>
                </Home>
            </App>
        </BrowserRouter>);

        const main = screen.getByRole('main');
        const catalogLink = within(main).getByRole('link', { name: 'Check the catalog' });

        userEvent.click(catalogLink);

        await waitFor(() => {
            const searchInput = screen.getByPlaceholderText('Name or location');
            const selectElements = screen.getAllByRole('combobox');
            expect(searchInput).toBeVisible();

            selectElements.forEach(el => expect(el).toBeVisible());
        });
    });

    it('Register link works', async () => {
        render(
            <BrowserRouter>
                <App>
                    <Home />
                </App>
            </BrowserRouter>
        );

        const main = screen.getByRole('main');
        const registerLink = within(main).getByRole('link', { name: 'Register' });

        console.log(registerLink);
        userEvent.click(registerLink);

        await waitFor(() => {
            ['Email', 'Password', 'Repeat password']
                .map((el) => screen.getByPlaceholderText(el))
                .forEach(el => expect(el).toBeVisible());
        });
    });


如果我使用screen.debug(),我可以清楚地看到呈现的是Catalog组件而不是Home,因此无法访问Register链接。
我尝试在每次测试后使用@testing-library/react中的cleanup函数来隔离每个测试。cleanup函数预计会卸载渲染组件并清理DOM,确保每个测试都有一个干净的状态。
我还尝试了各种各样的清理方法,比如完全删除清理,或者使用await cleanup()来确保它在进入下一个测试之前完成。
我试着自己运行测试,他们似乎工作。我做错了什么?如果你需要更多的信息,让我知道。

o8x7eapl

o8x7eapl1#

我知道你想做什么,你可以改变你的测试设置如下:

let BASE_URL = null;
afterEach(() => {
  // Cleaning the component and setting up the
  if (!BASE_URL) BASE_URL = window.location.origin;

  delete window.location;
  window.location = new URL(BASE_URL);
  cleanup();
});

字符串
那就是说:我建议你不要这么做--切换到MemoryRouter(正如你可以看到reactrouter的文档本身推荐的那样,请参阅那里的**“提示”**)。
如果你这样做,你不需要改变位置与技巧

render(
  <MemoryRouter>
    <App>
      <Home></Home>
    </App>
  </MemoryRouter>
);

注意:从您的原始代码来看,您实际上不需要以下内容来实现此功能

/* All this code from your snipped is not needed */
import { JSDOM } from 'jsdom';
const { window } = new JSDOM();
global.window = window;
// Mock the alert function
window.alert = vi.fn();

相关问题