Jest.js 将React单元测试从Enzyme迁移到React测试库

pftdvrlh  于 2023-03-27  发布在  Jest
关注(0)|答案(2)|浏览(147)

我最近继承了一个需要使用RTL的代码库(目前使用的是Enzyme)。很多Enzyme测试都非常简单,并且没有任何问题:

const render = ({ firstName, surname } = {}) => {
  const props = { firstName, surname };
  return shallow(<MyComponent {...props} />);
};

test('renders firstName and surname', () => {
  expect(
    render({
      firstName: 'My first name',
      surname: 'My surname',
    })
  ).toMatchSnapshot();
});

然而,我在将这个测试迁移到React测试库时遇到了问题-我有下面作为一个非常粗略的起点,但知道它不太正确。有人能为像这样的基础知识提供有用的文档或建议任何代码改进吗?TIA

test('renders firstName and surname', () => {
  props = { firstName, surname };
  render(<MyComponent {...props} />);

  expect(screen.getByText(props.firstName)).toBe('My first name');
  expect(screen.getByText(props.surname)).toBe('My surname');
});
8nuwlpux

8nuwlpux1#

作为一个同时使用这两种方法的人,我了解到RTL在概念上与酶非常不同。RTL不鼓励进行propAssert,相反,他们建议编写用户驱动的测试。因此,我的主要改进建议是在编写测试之前思考并问自己“用户现在看到了什么?”或“用户在屏幕上看到了什么?”。
在上面的测试中,你基本上是在检查,这些 prop 是否是你定义的,它们是如何在酶中完成的,但是当你停下来想一想,这是相当多余的。
我完全理解有些组件非常简单,没有太多的测试内容,所以在这种情况下,我会用下面的方式重写你的测试,以更符合RTL的精神,在这种情况下,就是“用户看到的是我期望他们看到的吗?”。我还建议把你的元素查询放在变量中,以提高可读性。

it('renders firstName and surname', () => {
  const props = {
    firstName: 'My first name',
    surname: 'My surname',
  };

  render(<MyComponent {...props} />);
  const firstName = screen.getByText(props.firstName);
  const surname = screen.getByText(props.surname);

  expect(firstName).toBeInTheDocument();
  expect(surname).toBeInTheDocument();
});
mtb9vblg

mtb9vblg2#

下面是修改后的代码及其解释:

test('renders firstName and surname', () => {
  props = { firstName, surname };
  const {asFragment} = render(<MyComponent {...props} />);

  // You might need to update snapshot
  // The observed diff should be DocumentFragment created by RTL
  expect(asFragment()).toMatchSnapshot();

  // Additionally, you can also assert the prop values 
  expect(screen.getByText(props.firstName)).not.toBe(null);
  expect(screen.getByText(props.surname)).not.toBe(null);
});

相关问题