当表单中所需的输入字段为空时,如何模拟提交处理程序未被调用?

Kib*_*tas 5 javascript unit-testing reactjs jestjs react-testing-library

我最近开始使用 Jest 和 React-testing-library 进行测试。但我遇到了一个小问题。我正在测试我的组件,如下所示:

\n
import React, { useState } from 'react';\n\nconst Login = () => {\n  const [username, setUsername] = useState<string>('');\n  const [password, setPassword] = useState<string>('');\n\n  const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {\n    event.preventDefault();\n  };\n\n  return (\n    <div>\n      <form onSubmit={handleSubmit} data-testid="loginForm">\n        <label>\n          Username:\n          <input\n            required\n            type="text"\n            data-testid="usernameText"\n            placeholder="e.g. JohnLukeThe3rd"\n            value={username}\n            onChange={(event) => setUsername(event.target.value)}\n            autoFocus\n          />\n        </label>\n        <label>\n          Password:\n          <input\n            required\n            type="password"\n            data-testid="passwordText"\n            placeholder="e.g. \xe2\x80\xa2\xe2\x80\xa2\xe2\x80\xa2\xe2\x80\xa2\xe2\x80\xa2\xe2\x80\xa2\xe2\x80\xa2\xe2\x80\xa2\xe2\x80\xa2\xe2\x80\xa2"\n            value={password}\n            onChange={(event) => setPassword(event.target.value)}\n          />\n        </label>\n        <input type="submit" data-testid="loginButton" value="Login" />\n      </form>\n    </div>\n  );\n};\n\nexport default Login;\n\n
Run Code Online (Sandbox Code Playgroud)\n

据我了解,提交表单时不会调用 onSubmit,但表单的必填输入字段为空。我通过在handleSubmit中插入console.log('Hey')来检查此行为,但没有打印任何内容。所以,我认为在我的测试中也应该发生同样的情况。当我检查输入为空时是否不会调用提交处理程序时,它应该会成功。但事实并非如此。它失败。

\n

这是测试代码:

\n
import React from 'react';\nimport {\n  render,\n  fireEvent,\n  cleanup,\n  RenderResult,\n} from '@testing-library/react';\nimport userEvent from '@testing-library/user-event';\nimport Login from '../components/Login';\n\ndescribe('<Login />', () => {\n  let screen: RenderResult;\n  beforeEach(() => {\n    screen = render(<Login />);\n  });\n  afterEach(cleanup);\n\n  describe('typing user info', () => {\n    it('shows username and password', async () => {\n      expect(screen.queryByDisplayValue('JohnLukeThe3rd')).toBeNull();\n      await userEvent.type(\n        screen.getByLabelText(/username/i),\n        'JohnLukeThe3rd',\n      );\n      await userEvent.type(screen.getByLabelText(/password/i), 'Password123');\n      expect(screen.queryByDisplayValue('JohnLukeThe3rd')).toBeInTheDocument();\n      expect(screen.queryByDisplayValue('Password123')).toBeInTheDocument();\n    });\n  });\n\n  describe('clicking login button', () => {\n    let loginButton: HTMLElement;\n    let submitHandler: jest.Mock;\n    let form: HTMLElement;\n\n    beforeEach(() => {\n      loginButton = screen.getByText(/login/i);\n      submitHandler = jest.fn((e) => e.preventDefault());\n      form = screen.getByTestId(/loginForm/i);\n      form.onsubmit = submitHandler;\n    });\n\n\n    // problem area here\n    it('does not call submit handler if fields empty', () => {\n      expect(submitHandler).not.toHaveBeenCalled();\n      userEvent.click(loginButton);\n      expect(submitHandler).not.toHaveBeenCalled();\n    });\n    // problem area ends\n\n\n    it('calls submit handler if fields non-empty', async () => {\n      expect(submitHandler).not.toHaveBeenCalled();\n      const usernameField = screen.getByTestId('usernameText');\n      const passwordField = screen.getByTestId('passwordText');\n      await userEvent.type(usernameField, 'JohnLukeThe3rd');\n      await userEvent.type(passwordField, 'Password123');\n      await userEvent.click(loginButton);\n      expect(submitHandler).toHaveBeenCalledTimes(1);\n    });\n  });\n});\n\n
Run Code Online (Sandbox Code Playgroud)\n

测试“如果字段为空则不调用提交处理程序”失败。我究竟做错了什么?我在任何地方都找不到有关带有必填输入字段的测试表单的任何信息。我做错了吗?谢谢。

\n

另外,想让你知道:我在测试中执行了 screen.debug() ,两个输入的值都是 'value=""'

\n