开始使用 Enzyme 和 Jest 测试 React 组件
Getting started testing React components with Enzyme and Jest
不幸的是,在我工作的地方,我们不对 React 组件进行单元测试。由于我也是这个行业的新手,所以我没有任何为软件编写单元测试的经验。这让我在尝试自学时陷入了一个奇怪的困境,因为我在网上看到的例子要么解释不清,要么就是不适合初学者。我最近检查了使用 Enzyme 和 Jest 测试 React Components,并认为这种组合看起来很有前途。
我的目标是: 我想找出正确的方法来测试 React props 从 parent 到child 组件。我正在使用 Jest 和 Enzyme,因此解决方案应该使用这两个模块的最佳实践。
为了简单起见,我想围绕两个示例组件提出这个问题。我们假设这些组件在串联使用时会在屏幕上生成一个用户列表,而不是您在现实世界中永远不会看到的名称。组件将被命名为:
- 用户列表(Parent)
- UserListItem(Child)
这是 UserList React 组件。为了尽量简化这个示例,我只是将要传递给 child 的数据放在本地状态中。假设此数据始终是 objects 的数组。
import React, { Component } from 'react'
import UserListItem from './user-list-item'
export default class UserList extends Component {
constructor(props) {
super(props)
this.state = {
users: [
{
userName: 'max',
age: 24
},
{
userName: 'susan',
age: 28
}
]
}
}
renderUsers = (list) => {
return this.state.users.map(user => <UserListItem key={user.userName} user={user} />)
}
render() {
return (
<ul>
{this.renderUsers()}
</ul>
)
}
}
现在,这里是 child 组件,UserListItem
import React, { Component } from 'react'
const UserListItem = ({ user }) => {
return (
<li>
<div>
User: {user.userName}
</div>
<div>
Age: {user.age}
</div>
</li>
)
}
export default UserListItem
通过在线阅读各种教程,我发现通过 Enzyme 进行浅层渲染是首选方法。我已经明白它是如何工作的,但我真正想要的是对道具的端到端和彻底测试。
此外,仅检查 React 组件是否被传递了特定的 prop 名称就足够了吗?或者我们是否还需要创建某种类型的伪数组,其中包含虚拟数据以提供给 child 组件?
对于您当前的组件,我会编写一个测试以确保正确呈现状态中的元素,例如:
it('should render two UserListItems', () => {
const cmp = shallow(<UserList />);
expect(cmp.find(UserList).length).toBe(2);
})
我还要测试发送到 children 的数据是否正确。在这种情况下,UserList
的 users
状态应该显示在每个 child UserListItem
.
的道具中
it('should send the correct data', () => {
const user = { userName: 'test', age: 22 };
const cmp = shallow(<UserList />);
cmp.setState({ users: [user] });
expect(cmp.find(UserListItem).props().user).toBe(user);
})
对于 UserListItem 组件,我会测试姓名和年龄是否正确呈现。
it('should render name and age', () => {
const user = { userName: 'test', age: 22 };
const cmp = shallow(<UserListItem user={user} />);
expect(cmp.find('div[children="User: test"]').length).toBe(1);
expect(cmp.find('div[children="Age: 22"]').length).toBe(1);
})
不幸的是,在我工作的地方,我们不对 React 组件进行单元测试。由于我也是这个行业的新手,所以我没有任何为软件编写单元测试的经验。这让我在尝试自学时陷入了一个奇怪的困境,因为我在网上看到的例子要么解释不清,要么就是不适合初学者。我最近检查了使用 Enzyme 和 Jest 测试 React Components,并认为这种组合看起来很有前途。
我的目标是: 我想找出正确的方法来测试 React props 从 parent 到child 组件。我正在使用 Jest 和 Enzyme,因此解决方案应该使用这两个模块的最佳实践。
为了简单起见,我想围绕两个示例组件提出这个问题。我们假设这些组件在串联使用时会在屏幕上生成一个用户列表,而不是您在现实世界中永远不会看到的名称。组件将被命名为:
- 用户列表(Parent)
- UserListItem(Child)
这是 UserList React 组件。为了尽量简化这个示例,我只是将要传递给 child 的数据放在本地状态中。假设此数据始终是 objects 的数组。
import React, { Component } from 'react'
import UserListItem from './user-list-item'
export default class UserList extends Component {
constructor(props) {
super(props)
this.state = {
users: [
{
userName: 'max',
age: 24
},
{
userName: 'susan',
age: 28
}
]
}
}
renderUsers = (list) => {
return this.state.users.map(user => <UserListItem key={user.userName} user={user} />)
}
render() {
return (
<ul>
{this.renderUsers()}
</ul>
)
}
}
现在,这里是 child 组件,UserListItem
import React, { Component } from 'react'
const UserListItem = ({ user }) => {
return (
<li>
<div>
User: {user.userName}
</div>
<div>
Age: {user.age}
</div>
</li>
)
}
export default UserListItem
通过在线阅读各种教程,我发现通过 Enzyme 进行浅层渲染是首选方法。我已经明白它是如何工作的,但我真正想要的是对道具的端到端和彻底测试。
此外,仅检查 React 组件是否被传递了特定的 prop 名称就足够了吗?或者我们是否还需要创建某种类型的伪数组,其中包含虚拟数据以提供给 child 组件?
对于您当前的组件,我会编写一个测试以确保正确呈现状态中的元素,例如:
it('should render two UserListItems', () => {
const cmp = shallow(<UserList />);
expect(cmp.find(UserList).length).toBe(2);
})
我还要测试发送到 children 的数据是否正确。在这种情况下,UserList
的 users
状态应该显示在每个 child UserListItem
.
it('should send the correct data', () => {
const user = { userName: 'test', age: 22 };
const cmp = shallow(<UserList />);
cmp.setState({ users: [user] });
expect(cmp.find(UserListItem).props().user).toBe(user);
})
对于 UserListItem 组件,我会测试姓名和年龄是否正确呈现。
it('should render name and age', () => {
const user = { userName: 'test', age: 22 };
const cmp = shallow(<UserListItem user={user} />);
expect(cmp.find('div[children="User: test"]').length).toBe(1);
expect(cmp.find('div[children="Age: 22"]').length).toBe(1);
})