reactjs - 如何通过 react 单元测试在多层自定义组件上触发事件

标签 reactjs typescript react-native unit-testing react-testing-library

我正在为我正在单元测试的功能编写测试用例。我想编辑嵌入在几个自定义组件中的文本字段,但我不知道如何访问它:

测试文件.test.tsx

it('should be able to change quantity', () =>{
  //Mock out dependent function with jest
  //Nothing here right now


  //Render with the props you want
  render(        
        <MainComponent /> );

  //Locate screen components for test
  const counter = screen.queryByTestId("counter");

  //Perform user actions
  fireEvent.change(counter, 4);   <--This is the line where I'm trying to access what I want

  //Measure against expect cases
  expect(counter).toBe(4);
});

主要组件.tsx

这是我要访问的组件。问题是,`fireEvent.change` 不起作用,因为它是一个自定义组件。至少,我认为这就是它不起作用的原因。
<Counter
  data-testid='counter'    <--data-testid is here right now
  containerMargin={{ marginTop: -5 }}
/>

计数器.tsx

`Counter` 里面是另一个自定义组件,`TextField`
<TextField
     {...props}
/>

文本字段.tsx

在 TextField 内部是我要访问的文本输入所在的位置:
<TextInput
  {...props}
/>

错误信息

当我尝试运行测试时,出现此错误:
  ●  Test › should be able to change quantity

Unable to fire a "change" event - please provide a DOM element.

  189 |
  190 |     //Perform user actions
> 191 |     fireEvent.change(counter, 4);
      |               ^
  192 |
  193 |     //Measure against expect cases
  194 |     expect(counter).toBe(4);

我不能将 data-testid 属性放入 TextFieldTextInput 本身,因为还有另一个 Counter 在我正在测试的页面的渲染中。任何建议或故障排除都会有所帮助,谢谢!

最佳答案

The getByTestId query is an escape hatch.

In the spirit of the guiding principles, it is recommended to use this only after the other queries don't work for your use case. Using data-testid attributes do not resemble how your software is used and should be avoided if possible.

您的文本字段应该可以访问。和 accessibility应该利用它来访问元素。

const input = screen.getByRole('textbox', {name: t('priceMultiple')})
// or
const input = screen.getByLabelText(t('priceMultiple'))

Using fireEvent directly is also an escape hatch.

Most projects have a few use cases for fireEvent, but the majority of the time you should probably use @testing-library/user-event.

此建议进一步解释in the user-event docsin this blog post .

await userEvent.type(input, '4')

请注意,在大多数情况下,建议设置用户事件实例并描述用户在组件上执行的确切工作流程。所以大多数测试应该看起来像这样。

const user = userEvent.setup()
render(<MyComponent/>)

await user.tripleClick(screen.getByRole('textbox', {name: /some label/}))
await user.keyboard('4')

// ... assert that the component output is correct ...

await user.tab()
await user.keyboard('567') // edit another field

// ... perform more assertions ...

关于reactjs - 如何通过 react 单元测试在多层自定义组件上触发事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70838945/

相关文章:

reactjs - npm 开始报错

reactjs - 为什么 Jest 中的 TestUtils.Simulate.click 直接在 React Components 上使用时不起作用?

javascript - 如何序列化可观察数组的执行

firebase - 存储和使用 Firebase 身份验证 token 对我的服务器进行 API 调用

ios - 是否建议将 React Native 应用程序的核心逻辑托管在云中?

reactjs - 不能将 React Icons 组件用作对象值 typescript

html - 计算div中将使用多少行?

Angular:无法解析组件的所有参数

javascript - 运算符 '>' 不能应用于 Angular 8 中的类型 'void' 和 'number'

javascript - 使用 `...` 从现有对象创建新对象时出错 : In this environment the sources for assign MUST be an object