React 测试库 - fireEvent 不会更改输入值

Maa*_*nPL 8 javascript testing reactjs jestjs react-testing-library

\n我正在学习 React 测试,但 fireEvent 不会改变我输入的值。无奈,不知道为什么?

\n

我正在渲染 BuyPlace 组件。在这个组件中,我有一个包含输入组件的表单(这些组件只是带有输入的标签,我将道具传递给表单上的这个组件)。

\n

在 screen.debug() 上,我可以看到我的组件是使用此表单和所有这些输入正确呈现的。

\n

另外,我的输入在我的测试中被正确捕获,我检查了这一点。

\n

这是我的测试:

\n
test("should change input value", async () => {\nrender(\n<HashRouter>\n<UserContext.Provider value={{ user: true }}>\n<BuyPlace />\n</UserContext.Provider>\n</HashRouter>\n);\nconst nameInputEl = screen.getByPlaceholderText("Podaj w\xc5\x82asn\xc4\x85 nazw\xc4\x99");\nfireEvent.change(nameInputEl, {\ntarget: { value: "Micha\xc5\x82" },\n});\nawait waitFor(() => {\nexpect(nameInputEl.value).toBe("Micha\xc5\x82");\n});\n});\n
Run Code Online (Sandbox Code Playgroud)\n

测试未通过。当然,我的应用程序运行正常,但在测试中它不起作用。

\n

这是我的组件上的handleInputChange:

\n
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement> | React.ChangeEvent<HTMLTextAreaElement>) => {\nsetInputValues((prevValues) => {\nreturn {\n...prevValues,\n[e.target.name]: e.target.value,\n}\n});\n};\n
Run Code Online (Sandbox Code Playgroud)\n

我发现的每个解决方案都不起作用...我的输入值始终是空字符串。有人可以帮我弄这个吗?我想学习编写好的测试,但我不知道问题出在哪里。

\n

编辑\n我在 screen.debug() 上看到了一些有趣的东西。

\n

我在测试中的输入在没有 onchange 属性的情况下呈现,这在测试中正常吗?看一下这个:

\n
                   <input\n                    id="name"\n                    name="name"\n                    placeholder="Podaj w\xc5\x82asn\xc4\x85 nazw\xc4\x99"\n                    type="text"\n                    value=""\n                  />\n
Run Code Online (Sandbox Code Playgroud)\n

在我渲染的父组件上,我有handleInputChange,并且该函数正在传递给输入组件。在现场,一切正常,但在测试中却不然……也许这就是 fireEvent 不起作用的原因?

\n

但为什么在测试时我的输入没有 onchange 属性?

\n

编辑2解决方案

\n

哇,三天后我找到了问题所在!

\n

问题出在 setState 函数中,它改变了值。我有:

\n
const myValues = (object with values);\n\nsetState((previousValues) => {\n...previousValues,\n[e.target.name]: e.target.value\n})\n
Run Code Online (Sandbox Code Playgroud)\n

但在对此进行更改后:

\n
setState({\n...myValues,\n[e.target.name]: e.target.value\n})\n
Run Code Online (Sandbox Code Playgroud)\n

我的测试通过了。所以我不能在 setState 上使用 previousState 回调 - 这就是我的测试不正确的原因。\n但是...为什么?这是我的问题!

\n

Jon*_*ern 5

建议使用userEvent超过fireEvent. 特别是如果您使用的是 Material-UIfireEvent ,因为使用而不是存在问题userEvent

测试库文档的注释

大多数项目都有一些 fireEvent 用例,但大多数时候您可能应该使用@testing-library/user-event。

而不是fireEvent.change你会做这样的事情

userEvent.type(nameInputEl, 'Michal');
Run Code Online (Sandbox Code Playgroud)

  • 非常感谢 - 我也尝试过 userEvent,它不起作用......这是不可能的! (3认同)
  • 问题出在哪里?我面临着同样的问题。我在 onChange 处理程序中放置了一个 console.log() ,我在那里得到控制台输出,但是 `expect(input.value).toBe("11");` 这一行给出错误,因为 value 是 "" 空字符串。Screen.debug() 显示正在渲染并用于触发更改事件的正确输入 (2认同)