我有一些正在进行的测试,正在按预期方式工作:
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块一定不能正常工作。这很奇怪,因为我们已经进行了酶测试,并且设置和拆卸工作正常。
我遇到了一个单独的问题,但在其中发现了[[your问题的可能答案。
Jestdescribe
块按顺序运行,然后运行任何测试。 Source因此,除了变量作用域外,您基本上不应该在describe块中执行代码。如果需要设置变量或呈现可在多个测试中使用的模拟,请将其放在生命周期方法中,例如beforeAll
或beforeEach
。
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。
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
- 在查询中指定
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) }
- 为每个
render
指定不同的基本元素