ReactJS - mockComponent()



当我们在应用程序中使用像 React 这样的库时,我们应该定期测试我们的组件。但是,检查它们有时可能很困难,因为组件可能依赖于其他组件。这就是 mockComponent() 函数的用武之地。

假设我们有一个代码组件,它有一个我们想要检查的按钮或表单,但它依赖于其他组件。我们可以使用 mockComponent() 来创建这些其他组件的虚假模型,这样我们就可以在不实际使用它们的情况下测试我们的代码。

语法


mockComponent(
	 	componentClass,
	 	[mockTagName]
)

参数

  • componentClass - 这是我们想要模拟的组件。它是我们想要创建用于测试目的的虚假版本的类或模块。
  • [mockTagName] (可选) − 此参数位于方括号中,这意味着它不是必需的。如果我们提供此参数,它指定了假组件将模仿的 HTML 标签名称。如果我们不提供它,则默认标签名称为 <div>。

返回值

mockComponent 函数返回给定组件类的模拟或虚假版本。这使我们能够隔离和测试我们的组件,而无需实际使用其依赖项。

如何使用 mockComponent() 函数?

我们调用 mockComponent() 并为其提供我们想要测试的组件。我们还可以告诉它虚假组件应该看起来像什么样的 HTML 标签(通常是 <div>)。通常位于真实组件内的任何内容都将被放入虚假组件中。

所以,mockComponent() 就像制作一个组件的假装版本来帮助我们测试我们的代码。需要注意的是,在 React 中有更新更好的方法来做到这一点,比如使用 jest.mock(),但 mockComponent() 是一种较旧的方法,我们可能仍会在某些代码中遇到。

例子

示例 - 模拟按钮组件

这是一个我们如何在 React 中使用 mockComponent() 的例子 -

假设我们有一个名为 Button.js 的 React 组件,我们想要测试它。这个组件依赖于另一个叫做 Icon.js 的组件,我们想用 mockComponent() 来模拟它。

Button.js


import React from 'react';
import Icon from './Icon';

function Button() {
	 	return (
	 	 	 <button>
	 	 	 	 	<Icon name="star" />
	 	 	 	 	Click me
	 	 	 </button>
	 	);
}

export default Button;

现在,我们可以借助 mockComponent() 为 Button 组件创建一个测试来模拟 Icon 组件。所以我们可以使用一个测试文件来做,我们称之为 Button.test.js -

Button.test.js


import React from 'react';
import { shallow } from 'enzyme'; // Use Enzyme for testing
import { mockComponent } from 'react-dom/test-utils'; // Importing mockComponent

import Button from './Button';

// Mock the Icon component
const MockedIcon = mockComponent(Icon);

test('Button renders with a mocked Icon', () => {
	 	const wrapper = shallow(<Button />);
	 	expect(wrapper.contains(<MockedIcon name="star" />)).toBeTruthy();
});

在这个例子中,我们从 react-dom/test-utils 导入 mockComponent,并使用 mockComponent(Icon) 来创建 Icon 组件的模拟版本。然后,在我们的 Button 组件测试中使用模拟版本。

示例 - 模拟表单组件

我们将定义一个简单的 React 应用程序,其中渲染了 Form 组件,我们将使用 mockComponent 创建 Form 组件的模拟版本以进行测试。Form 组件采用 onSubmit 属性来处理表单提交。

我们的测试应用程序会测试表单是否呈现,并且可以通过与输入字段和提交按钮交互来模拟表单提交。这里 mockComponent 函数用于创建 Form 组件的模拟版本,以便进行测试。

Form.js


import React from 'react';

const Form = ({ onSubmit }) => (
	 	<form onSubmit={onSubmit}>
	 	 	 <input type="text" />
	 	 	 <button type="submit">Submit</button>
	 	</form>
);

export default Form;

App.js


import React from 'react';
import { render } from '@testing-library/react';
import { mockComponent } from 'your-testing-library'; // Replace with testing library
import Form from './Form';

const MockedForm = mockComponent(Form, 'div');
test('renders a form', () => {
	 	const { getByText } = render(<MockedForm />);
	 	const submitButton = getByText('Submit');
	 	expect(submitButton).toBeInTheDocument();
});

示例 - 使用子组件模拟父组件

这个 React 应用程序由一个 ParentComponent 组成,该 ParentComponent 呈现一个名为 ChildComponent 的子组件。出于测试目的,使用 mockComponent 函数将 ChildComponent 替换为模拟版本。让我们看看下面的应用程序 -

ParentComponent.js


import React from 'react';
import ChildComponent from './ChildComponent';

const ParentComponent = () => (
	 	<div>
	 	 	 <p>This is a parent component</p>
	 	 	 <ChildComponent />
	 	</div>
);

export default ParentComponent;

App.js


import React from 'react';
import { render } from '@testing-library/react';
import { mockComponent } from 'your-testing-library'; // Replace with testing library

import ParentComponent from './ParentComponent';

const MockedChildComponent = mockComponent(() => <div>Mocked Child</div>, 'div');
const MockedParentComponent = mockComponent(ParentComponent, 'div');

test('renders a parent component with a mocked child', () => {
	 	const { getByText } = render(<MockedParentComponent />);
	 	const parentText = getByText('This is a parent component');
	 	const mockedChildText = getByText('Mocked Child');
	 	
	 	expect(parentText).toBeInTheDocument();
	 	expect(mockedChildText).toBeInTheDocument();
});

总结

mockComponent() 是一个有用的工具,用于通过生成依赖组件的模拟版本来简化 React 组件测试。它通过确保测试针对单个组件的功能而不是其依赖项来实现有效的测试。mockComponent() 有一些替代品,比如 jest.mock(),mockComponent() 仍然是用于测试 React 组件的有价值的遗留 API。