如何测试子组件是不是已呈现?
Posted
技术标签:
【中文标题】如何测试子组件是不是已呈现?【英文标题】:How do I test that a child component is rendered?如何测试子组件是否已呈现? 【发布时间】:2020-05-19 08:11:35 【问题描述】:在酶中,您可以像这样检查子组件的存在:
expect(wrapper.find(ChildComponent)).toHaveLength(1)
反应测试库中这个测试的等价物是什么?我发现的所有在线示例都只涵盖了寻找 dom 元素的非常简单的测试——没有一个包含渲染子组件的示例。如何找到子组件?
【问题讨论】:
可能是expect(wrapper).toContain('ChildComponent')
?
【参考方案1】:
因为query*
返回null
如果没有找到元素你可能只是
expect(queryByTestId('test-id-you-provided')).toEqual(null);
expect(queryByTestId('some-other-test-id-you-provided')).not.toEqual(null);
如果找不到元素,getBy*
也会抛出。所以下一个应该也可以工作
getByTestId('test-id-you-provided');
【讨论】:
【参考方案2】:你不应该检查你的子组件是否被渲染,因为它正在测试实现细节(哪个测试库不鼓励你这样做)。
您可以检查子组件中的某些文本是否已呈现,或者您可以将 data-testid 提供给子组件中的包装器元素,然后使用来自 @testing-library/jest-dom 的 .toBeInTheDocument
expect(getByText(/some text/i)).toBeInTheDocument();
或
expect(getByTestId('your-test-id')).toBeInTheDocument();
更新:示例
// Child Component
function ChildComponent()
return <div>Child Element</div>;
;
// Parent
export default function Parent()
return (
<div className="App">
<ChildComponent />
</div>
);
测试:
import render from "@testing-library/react";
import "@testing-library/jest-dom/extend-expect";
import Parent from "./App";
test("test child component", () =>
const getByText = render(<Parent />);
expect(getByText(/child element/i)).toBeInTheDocument();
);
【讨论】:
我可以获得完整的测试样本吗? 你不希望括号是这样的:expect(getByText(/some text/i)).toBeInTheDocument();
?
@ninjastar 感谢您指出这一点。更新答案。
@NkoroJosephAhamefula 这完全取决于您的用例。这只是一个如何测试子组件是否被渲染的例子。这个周末我会尝试创建一个简单的例子。
You shouldn't check if your child component is rendered or not, because it's testing implementation details
- 这根本不是真的。例如,我想检查父组件在获取数据时是否显示微调器。这不是实现细节,除非我寻找特定的微调器类等。【参考方案3】:
我为此使用了React Test Renderer:
import TestRenderer from 'react-test-renderer';
import ItemList from 'components/ItemList';
import LoadingIndicator from 'components/LoadingIndicator';
test('renders loading indication', () =>
const testRenderer = TestRenderer.create(
<ItemList items=[] isLoading=true/>
);
const testInstance = testRenderer.root;
testInstance.findByType(LoadingIndicator);
);
我不认为它是“测试实现细节”,恰恰相反——LoadingIndicator 组件可以在不需要修复测试用例的情况下进行修改。
【讨论】:
感谢@Mikhail Batcer 控制预期行为的一种更好的做法是expect(() => root.findByType(WichedComponent)).not.toThrow()
【参考方案4】:
您可以使用@testing-library/jest-dom 库。
组件:
<div role="root">
<div data-testid="parent">
<div data-testid="child">
content
</div>
</div>
</div>
测试:
import '@testing-library/jest-dom'
import render from '@testing-library/react';
describe('My component', () =>
test('should render component2', () =>
const getByRole, getByTestId = render(<Component/>);
const root = getByRole('root');
const parent = getByTestId('parent');
const child = getByTestId('child');
expect(root).toContainElement(parent);
expect(parent).toContainElement(child);
expect(child).not.toContainElement(parent); // Pass
expect(child).toContainElement(parent); // Throw error!
);
);
另一种解决方案是使用@testing-library/react
库中的within
函数:
import within from '@testing-library/react';
...
expect(within(parent).queryByTestId('child')).not.toBeNull();
【讨论】:
以上是关于如何测试子组件是不是已呈现?的主要内容,如果未能解决你的问题,请参考以下文章
使用 react-testing-library 时如何测试组件是不是使用正确的道具呈现?
ReactJs:如何创建一个包装器组件,该组件在单击时会执行某些代码并呈现子组件?