Jestjs React测试库清理不起作用';我们来描述一下博克斯

Jestjs React测试库清理不起作用';我们来描述一下博克斯,jestjs,react-testing-library,Jestjs,React Testing Library,我有一些正在进行的测试,这正按预期工作: describe('Parent', () => { afterEach(() => { cleanup(); jest.resetModules(); }); describe('Test 1', () => { const wrapper = render( <MockProvider> &l

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

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);
        });
    });
});
description('Parent',()=>{
之后(()=>{
清理();
jest.reset模块();
});
描述('测试1',()=>{
常量包装器=渲染(
,
);
测试('1',()=>{
expect(wrapper.baseElement).toMatchSnapshot();
expect(wrapper.getByText('Apply').disabled).toBe(true);
});
});
描述('测试2',()=>{
测试('1',()=>{
常量包装器=渲染(
,
);
log(wrapper.getByText('Apply')。已禁用);
期望(1),期望(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);
        });
    });
});
description('Parent',()=>{
之后(()=>{
清理();
jest.reset模块();
});
描述('测试1',()=>{
常量包装器=渲染(
,
);
测试('1',()=>{
expect(wrapper.baseElement).toMatchSnapshot();
expect(wrapper.getByText('Apply').disabled).toBe(true);
});
});
描述('测试2',()=>{
常量包装器=渲染(
,
);
测试('1',()=>{
log(wrapper.getByText('Apply')。已禁用);
期望(1),期望(1);
});
});
});
我得到的错误是

找到多个包含以下文本的元素:Apply


我可以在控制台中看到组件被渲染了两次,因此我认为清理功能在描述块方面一定不能正常工作。这很奇怪,因为我们已经进行了酶测试,设置和拆卸对这些测试很有效

我遇到了一个单独的问题,但在中间找到了你的问题的可能答案

Jest
描述在任何测试运行之前按顺序运行的


所以,除了变量作用域之外,基本上不应该在descripe块中执行代码。如果您需要设置一个变量或呈现一个在多个测试中使用的模拟,请将其放入生命周期方法中,如
beforeal
beforeach
要理解这一点,我们需要了解一点关于
Jest
如何运行我们的测试以及
React测试库如何呈现我们的组件


开玩笑 考虑下面的代码,并尝试猜测输出将是什么:

descripe('First descripe',()=>{
console.log('First description');
它('第一次测试',()=>{
console.log(“第一次测试”);
});
});
描述('第二描述',()=>{
log('Second description');
它('第二次测试',()=>{
console.log(“第二次测试”);
});
});
输出(悬停查看):

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

请注意,所有
descripe
方法都是在测试开始运行之前初始化的

这应该已经让您了解了这个问题,但是现在让我们看看RTL


反应测试库 考虑下面的代码,并尝试猜测DOM在控制台中的外观:

const Greeting=()=>“你好世界”;
描述('第一次描述',()=>{
const wrapper=render();
它('第一次测试',()=>{
log(wrapper.debug());
});
});
描述('第二描述',()=>{
render();
});
输出(悬停查看):

Hello world
Hello world

当我们没有为
render
函数指定基本元素时,它总是使用相同的
document.body

当我们不指定自定义容器时,包装
Hello world
元素由RTL添加

默认情况下,所有RTL查询都绑定到基本元素--
document.body

所以,

getByText('Hello world');//将找到两个元素并抛出

这就是
render
函数的外观。(半伪码)

if(!baseElement){
baseElement=document.body//body将在渲染中共享
}
如果(!容器){
baseElement.appendChild(document.createElement('div'))//包装我们的组件
}
render(组件、容器)
返回{容器,baseElement,…getQueriesForElement(baseElement)}

要解决这个问题, 执行以下操作之一:

  • it
    test
    方法中调用
    render
  • 在查询中指定
    容器
  • 为每个
    渲染指定不同的基本元素

  • 另一个快速修复方法是在将组件传递到
    render()之前用“React.Fragment”包装组件

    test('should find text in',()=>{
    常量{getByText}=render()
    const divElement=getByText(/Find Text/i)
    expect(divElement).toBeInTheDocument()
    })
    
    为什么要尝试以这种方式渲染?我认为descripe块会设置case,然后test会有断言。我不确定它是否能以这种方式工作。我认为每个渲染都必须是独立的,你不能重复使用。哇,你的答案确定了我所需要的,谢谢
    test ('should find text in <Component />', () => {
       const {getByText} = render (<><Component /></>)
       const divElement = getByText (/Find Text/i)
       expect (divElement).toBeInTheDocument ()
    })