我想更改React测试库中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' } })
,但这不起作用,因为它返回错误:The given element does not have a value setter
。元素不是在其e.target.value
属性上使用onChange
吗?我在做什么错了?
答案 0 :(得分:11)
这里的问题是,当我们使用Material UI时,它将呈现其中具有元素之一的 TextField组件作为输入字段。 并且只有“输入”具有吸气剂和吸气剂。因此,在获取TextField之后,您可以使用DOM对象的 querySelector()获取TextField的“ input”元素。
const field = getByTestId('input-email').querySelector('input');
// now fire your event
fireEvent.change(field, { target: { value: 'abcd@xyz.com' } });
答案 1 :(得分:8)
这里的问题是TextField是MaterialUI中的抽象。它由FormControl,Label和Input组成。解决此问题的干净方法是:
InputProps
属性的文本字段上添加data-testid
。// YourComponent.js
<TextField
onChange={event => setContent(event.target.value)}
id="content"
inputProps={{ "data-testid": "content-input" }}
value={content}
label="Content"
/>
// YourComponent.test.js
const contentInput = getByTestId("content-input");
fireEvent.change(contentInput, {
target: { value: "new content" }
});
// and then assert stuff in here
答案 2 :(得分:0)
您可以在支持该事件的元素上使用fireEvent.change
,例如<input>
。就您而言,我不确定您要选择什么。您可以尝试debug(userInput)
查看返回的内容。
答案 3 :(得分:0)
我测试了答案和评论,唯一对我有用的解决方案是 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
更多here