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

IT技术 javascript unit-testing reactjs jestjs enzyme
2021-04-27 09:13:47

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

我的目标是:我想找出正确的方法来测试 React props 从父组件到子组件是否一直正常工作。我正在使用 Jest 和 Enzyme,因此解决方案应该使用这两个module的最佳实践。

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

  1. 用户列表(父级)
  2. UserListItem(孩子)

这是UserList React 组件。为了希望简化这个例子,我只是把将要传递给孩子的数据放在本地状态。让我们假设此数据将始终是一个对象数组。

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>
    )
  }
}

现在,这是子组件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

通过在线阅读各种教程,我发现通过酶进行浅层渲染是首选方法。我已经明白这是如何工作的,但我真正想要的是对props的端到端和彻底的测试。

另外,仅仅检查 React 组件是否传递了特定的 prop 名称就足够了吗?或者我们是否还需要创建某种类型的带有虚拟数据的假数组来提供给子组件?

1个回答

对于您当前的组件,我会编写一个测试,以确保正确呈现状态上的元素,例如:

it('should render two UserListItems', () => {
  const cmp = shallow(<UserList />);

  expect(cmp.find(UserList).length).toBe(2);
})

我还会测试发送给孩子们的数据是否正确。在这种情况下,users状态UserList应该出现在每个孩子的props中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);
})