Eva*_*nss 14 jestjs react-testing-library
我有一些正在进行的测试,这是按预期工作的:
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);
});
});
});
Run Code Online (Sandbox Code Playgroud)
但是,当我将第二个渲染函数移出测试时,它会出错:
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);
});
});
});
Run Code Online (Sandbox Code Playgroud)
我得到的错误是
找到多个带有文本的元素:Apply
我可以在控制台中看到组件被渲染了两次,所以我认为清理功能对于描述块一定不能正常工作。这很奇怪,因为我们已经进行了酶测试,并且设置和拆卸对这些都很好。
Dou*_*oug 14
要理解这一点,我们需要了解一点关于如何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');
});
});
Run Code Online (Sandbox Code Playgroud)
输出(悬停查看):
第一个描述
第二个描述
第一个测试
第二个测试
请注意,所有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 />);
});
Run Code Online (Sandbox Code Playgroud)
输出(悬停查看):
<body><div>Hello world</div><div>Hello world</div></body>
当我们没有为render函数指定一个基本元素时,它总是使用相同的document.body
当我们不指定自定义容器时,<div>元素包装Hello world由 RTL 添加。
默认document.body情况下,所有 RTL 查询都绑定到基本元素——在这种情况下。
所以,
getByText('Hello world'); // will find two elements and throw
Run Code Online (Sandbox Code Playgroud)
这就是函数的RTL 代码的样子render。(半伪代码)
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) }
Run Code Online (Sandbox Code Playgroud)
执行以下操作之一:
render在itortest方法内部调用container在查询中指定render| 归档时间: |
|
| 查看次数: |
4016 次 |
| 最近记录: |