reactjs - 使用 React 测试库测试登录功能

标签 reactjs jestjs react-testing-library

我正在尝试对 React SignIn 组件(使用 React 测试库和 Jest)进行单元测试,以实现两项功能:1)成功登录,2)登录失败(找不到电子邮件),这会呈现错误信息。然而,模拟函数似乎从未被调用过,结果我陷入了困境,我无法弄清楚我的问题出在哪里。我假设我错误地设置了模拟函数,但我不能肯定地说。我尝试了几种不同的方式设置模拟函数,但收到相同的错误。正如您将在我的测试文件中看到的,我希望在通过单击“登录”按钮提交表单时调用模拟函数一次,但它从未被调用。

SignIn 组件的结构如下:

import React from "react";
import { signIn } from "next-auth/client"

const SignIn = () => {
  const [email, setEmail] = React.useState("")

  // This function calls the signIn function from next-auth/client
  const validateEmail = async () => {
    await signIn("email", { email })
  }

  return (
    <div>
      <Card>
        <Logo />
        <Form onSubmit={validateEmail}>
          <div>
            <Email
              name="email"
              label="Email"
              testKey="email"
              afterChange={(e) => {
                setEmail(e.target.value)
              }}
            />
          </div>
        </Form>
        <div className="sign-up">
          Don{"'"}t have an account? <Link href="/sign-up">Sign up.</Link>
        </div>
      </Card>
    </div>
  )
}

export default SignIn

Form 组件是 SignIn 组件的子组件,接受 validateEmail 作为 props,并最终在辅助函数中使用,该函数在调用 SignIn 函数之前验证和清理数据,如下所示。

const Form = ({ validateEmail }) => {
  const handleSubmit = async (event) => {
    // Does some validation, formatting, etc.
    await validateEmail(event)
  }

  return (
    <form onSubmit={handleSubmit}>
      {children}
        {onSubmit && (
          <Button type="submit">
            Sign in
          </Button>
        )}
    </form>
  )
}

export default Form

我正在尝试对 SignIn 组件进行单元测试,并希望模拟我从“next-auth/client”导入的登录函数。但是,当我单击“登录”按钮并提交表单时,看起来并没有调用该函数,我不太明白为什么。我的测试如下所示:

import "@testing-library/jest-dom"
import { configure, fireEvent, render, waitFor } from "@testing-library/react"
import user from "@testing-library/user-event"
import { signIn } from "next-auth/client"
import React from "react"
import SignIn from "../../pages/auth/sign-in"

jest.mock("next-auth/client", () => {
  return {
    signIn: () => { ok: true }
  }
})

test("signs in successfully", async () => {
  const validEmail = "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="295f4845404d4c44484045695d4c5a5d074a4644" rel="noreferrer noopener nofollow">[email protected]</a>"
  const authConfig = { callbackUrl: undefined, redirect: false }

  const { getByTestId, getByText } = render(<SignIn />)
  const emailInput = getByTestId(/email/i)
  const signInButton = getByText(/sign in/i)

  user.type(emailInput, validEmail)
  fireEvent.click(signInButton)

  expect(signIn).toHaveBeenCalledTimes(1) // Is called 0 times and test fails
})

一如既往,我们非常感谢任何帮助/建议。

最佳答案

无需手动模拟 signIn 函数,只需使用 Jest 的 automock 即可。

jest.mock("next-auth/client")

这样 Jest 就会自动为您模拟 next-auth/client 中的所有函数。

它在您的情况下不起作用的原因是您正在使用显式函数覆盖 Jest 模拟。 signIn 变量实际上是您传递的函数,即 () => { ok: true },而不是 Jest 模拟实例。

关于reactjs - 使用 React 测试库测试登录功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69521225/

相关文章:

javascript - 我将如何在 react 测试库中测试 react 路由器路由参数?

arrays - ReactJS如何在分页中一次显示5页码

javascript - 如何为 Material UI 模板使用从右到左的选项?

javascript - 数据完全渲染时的 React/Meteor 初始化函数

javascript - 如何使用 Promise 创建 Jest 模拟函数?

javascript - Jest 的匹配器错误 : received value must be a function

reactjs - 使用钩子(Hook)触发子组件( react 表)的重新渲染

reactjs - 在 useEffect Hook 中使用 axios 取消 token 时如何修复失败的测试

react-select - 如何将 data-testid 属性添加到 react-select 组件

javascript - 接下来使用 React 测试库进行 seo 测试