反应测试库清理在Jest的describe bocks中不起作用

问题描述 投票:4回答:2

我有一些正在进行的测试,正在按预期方式工作:

describe('Parent', () => {
    afterEach(() => {
        cleanup();
        jest.resetModules();
    });

    describe('Test 1', () => {
        const wrapper = render(
            <MockProvider>
                <MyComponent />
            </MockProvider>,
        );

        test('1 ', () => {
            expect(wrapper.baseElement).toMatchSnapshot();
            expect(wrapper.getByText('Apply').disabled).toBe(true);
        });
    });

    describe('Test 2', () => {
        test('1 ', () => {
            const wrapper = render(
                <MockProvider>
                    <MyComponent />
                </MockProvider>,
            );
            console.log(wrapper.getByText('Apply').disabled);
            expect(1).toBe(1);
        });
    });
});

但是,当我将第二个渲染功能移出测试时却出错:

describe('Parent', () => {
    afterEach(() => {
        cleanup();
        jest.resetModules();
    });

    describe('Test 1', () => {
        const wrapper = render(
            <MockProvider>
                <MyComponent />
            </MockProvider>,
        );

        test('1 ', () => {
            expect(wrapper.baseElement).toMatchSnapshot();
            expect(wrapper.getByText('Apply').disabled).toBe(true);
        });
    });

    describe('Test 2', () => {
        const wrapper = render(
            <MockProvider>
                <MyComponent />
            </MockProvider>,
        );
        test('1 ', () => {
            console.log(wrapper.getByText('Apply').disabled);
            expect(1).toBe(1);
        });
    });
});

我得到的错误是

发现带有文本的多个元素:应用

我可以在控制台中看到该组件被渲染两次,因此我认为清除函数对于describe块一定不能正常工作。这很奇怪,因为我们已经进行了酶测试,并且设置和拆卸工作正常。

jestjs react-testing-library
2个回答
0
投票

我遇到了一个单独的问题,但在其中发现了[[your问题的可能答案。

Jest describe块按顺序运行,然后运行任何测试。 Source

因此,除了变量作用域外,您基本上不应该在describe块中执行代码。如果需要设置变量或呈现可在多个测试中使用的模拟,请将其放在生命周期方法中,例如beforeAllbeforeEach


0
投票
要了解这一点,我们需要对Jest如何运行我们的测试以及React Testing Library如何呈现我们的组件有一点了解。


笑话

考虑下面的代码,然后

尝试猜测输出是什么:

describe('First describe', () => { console.log('First describe'); it('First test', () => { console.log('First test'); }); }); describe('Second describe', () => { console.log('Second describe'); it('Second test', () => { console.log('Second test'); }); });

输出(悬停查看):

首先描述二描述第一次测试第二次测试

请注意,所有describe方法都在测试开始运行之前进行了初始化。

这应该已经使您对问题有所了解,但是现在让我们看一下RTL。


反应测试库

请考虑以下代码,并尝试猜测DOM在控制台中的外观:

const Greeting = () => 'Hello world'; describe('First describe', () => { const wrapper = render(<Greeting />); it('First test', () => { console.log(wrapper.debug()); }); }); describe('Second describe', () => { render(<Greeting />); });

输出(悬停查看):

<body> <div>Hello world</div> <div>Hello world</div> </body>

[当我们不为<body>函数指定基本元素时,它总是使用相同的<div>Hello world</div>

当我们不指定自定义容器时,RTL会添加包装<div>Hello world</div></body>元素。

默认情况下,所有[RTL查询都绑定到基本元素-在这种情况下为render

因此,

document.body

这是<div>功能的Hello world外观。 (半伪代码)

document.body

解决此问题

执行下列操作之一:

    getByText('Hello world'); // will find two elements and throw code in RTL方法内调用render
  1. 在查询中指定if(!baseElement) { baseElement = document.body // body will be shared across renders } if(!container) { baseElement.appendChild(document.createElement('div')) // wraps our component } ReactDOM.render(component, container) return { container, baseElement, ...getQueriesForElement(baseElement) }
  2. 为每个render指定不同的基本元素
© www.soinside.com 2019 - 2024. All rights reserved.