开始使用 Enzyme 和 Jest 测试 React 组件

Getting started testing React components with Enzyme and Jest

不幸的是,在我工作的地方,我们不对 React 组件进行单元测试。由于我也是这个行业的新手,所以我没有任何为软件编写单元测试的经验。这让我在尝试自学时陷入了一个奇怪的困境,因为我在网上看到的例子要么解释不清,要么就是不适合初学者。我最近检查了使用 Enzyme 和 Jest 测试 React Components,并认为这种组合看起来很有前途。

我的目标是: 我想找出正确的方法来测试 React props 从 parent 到child 组件。我正在使用 Jest 和 Enzyme,因此解决方案应该使用这两个模块的最佳实践。

为了简单起见,我想围绕两个示例组件提出这个问题。我们假设这些组件在串联使用时会在屏幕上生成一个用户列表,而不是您在现实世界中永远不会看到的名称。组件将被命名为:

  1. 用户列表(Parent)
  2. 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 的数据是否正确。在这种情况下,UserListusers 状态应该显示在每个 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);
})