React测试库:fireEvent在输入表单上更改时,给定元素没有值设置器

oto*_*ong 4 javascript react-testing-library

我想在React Testing库中更改Material UI 的值TextField。我已经设置了数据-testid。然后使用getByTestId我拿起输入元素。

// the component
<TextField
  data-testid="input-email"
  variant="outlined"
  margin="normal"
  required
  fullWidth
  id="email"
  label="Email Address"
  name="email"
  value={email}
  onChange={e => setEmail(e.target.value)}
  autoComplete="email"
  autoFocus
/>
// the test 
//...
let userInput = getByTestId('input-email')
fireEvent.change(userInput, { target: { value: 'correct@mail.com' } })
Run Code Online (Sandbox Code Playgroud)

但这不起作用,因为它返回错误:The given element does not have a value setter。元素不是e.target.value在其onChange属性上使用吗?我做错了什么?

Ash*_*wat 15

这里的问题是当我们使用 Material UI 时,它呈现TextField 组件,其中包含其中一个元素作为输入字段。并且只有“输入”有 getter 和 setter。因此,在获得 TextField 之后,您必须使用DOM 对象的querySelector()获取TextField的“输入”元素

const field = getByTestId('input-email').querySelector('input');
// now fire your event
fireEvent.change(field, { target: { value: 'abcd@xyz.com' } });
Run Code Online (Sandbox Code Playgroud)


Fra*_*dej 7

这里的问题是TextField是MaterialUI中的抽象。它由FormControl,Label和Input组成。解决此问题的干净方法是:

  • 首先,添加InputProps具有data-testid属性的TextField 。
// YourComponent.js

<TextField
  onChange={event => setContent(event.target.value)}
  id="content"
  inputProps={{ "data-testid": "content-input" }}
  value={content}
  label="Content"
/>
Run Code Online (Sandbox Code Playgroud)
  • 然后只需使用此ID进行查询。
// YourComponent.test.js

const contentInput = getByTestId("content-input");
fireEvent.change(contentInput, {
  target: { value: "new content" }
});

// and then assert stuff in here
Run Code Online (Sandbox Code Playgroud)


Gio*_*Gpx 5

您可以fireEvent.change在支持该事件的元素上使用,例如<input>. 就您而言,我不确定您要选择什么。你可以尝试看看debug(userInput)它返回了什么。


les*_*oes 5

我测试了答案和评论,唯一适合我的解决方案是 userEvent。

首先安装依赖 npm install --save-dev @testing-library/user-event

然后在您的测试文件中调用:

import { render, act } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
    
    ...
it('Awesome input test', async () => {
await act(async () => {
    const inputMessage = getByTestId('input-send-message');
    userEvent.type(inputMessage, 'My awesome text...');
  })
})
//expect goes here
Run Code Online (Sandbox Code Playgroud)

更多这里