【问题标题】:React: How to mock Auth0 for testing with JestReact:如何模拟 Auth0 以使用 Jest 进行测试
【发布时间】:2020-05-17 11:54:44
【问题描述】:

我正在使用 React(react-create-app 和 TypeScript)。使用 Auth0 进行登录。

我想用 Jest 编写测试,我发现这个资源基本上是唯一关于模拟 Auth0 对象的东西。

所以我的代码如下所示:

import React from "react";
import ReactDOM from "react-dom";
import TopBar from "./index";
import {
  useAuth0
} from "react-auth0-spa";

const user = {
  email: "johndoe@me.com",
  email_verified: true,
  sub: "google-oauth2|12345678901234"
};

// intercept the useAuth0 function and mock it
jest.mock("react-auth0-spa");

describe("First test", () => {
  beforeEach(() => {
    // Mock the Auth0 hook and make it return a logged in state
    useAuth0.mockReturnValue({
      isAuthenticated: true,
      user,
      logout: jest.fn(),
      loginWithRedirect: jest.fn()
    });
  });

  it("renders without crashing", () => {
    const div = document.createElement("div");
    ReactDOM.render( < TopBar / > , div);
  });
});

但我最终遇到了这个错误:

Property 'mockReturnValue' does not exist on type '() =&gt; IAuth0Context | undefined'.ts(2339)

我有点迷路了,任何帮助将不胜感激!

【问题讨论】:

    标签: javascript reactjs typescript jestjs auth0


    【解决方案1】:

    这是一个 TypeScript 错误。您需要输入模拟的useAuth0,因为原始类型没有称为mockReturnValue 的方法。像这样的东西应该可以工作:

    const mockedUseAuth0 = <jest.Mock<typeof useAuth0>>useAuth0;
    
    mockedUseAuth0.mockReturnValue({
      isAuthenticated: true,
      user,
      logout: jest.fn(),
      loginWithRedirect: jest.fn()
    });
    

    【讨论】:

      【解决方案2】:

      我自己花了一个小时左右才弄清楚这一点。问题源于修改模拟返回值后应用于 useAuth0 的类型不正确。我的解决方案是使用来自“ts-jest/utils”的模拟。您也可以将角色、范围等添加到用户对象。 (参见 adminUser 对象)

      import { render, screen } from "@testing-library/react";
      import { useAuth0 } from "@auth0/auth0-react";
      import { mocked } from "ts-jest/utils";
      
      const user = {
          email: "johndoe@me.com",
          email_verified: true,
          sub: "google-oauth2|12345678901234",
      };
      
      const adminUser = {
          email: "johndoe@me.com",
          email_verified: true,
          sub: "google-oauth2|12345678901234",
          "https://<<API_URL>>/roles": ["admin", "superuser"],
      };
      
      
      jest.mock("@auth0/auth0-react");
      
      const mockedUseAuth0 = mocked(useAuth0, true);
      
      describe("TopNav Component Tests - Logged in", () => {
          beforeEach(() => {
              mockedUseAuth0.mockReturnValue({
                  isAuthenticated: true,
                  user,
                  logout: jest.fn(),
                  loginWithRedirect: jest.fn(),
                  getAccessTokenWithPopup: jest.fn(),
                  getAccessTokenSilently: jest.fn(),
                  getIdTokenClaims: jest.fn(),
                  loginWithPopup: jest.fn(),
                  isLoading: false,
              });
          });
          test("Logout Button displays when logged in", () => {
              render(
                      <TopNav />
              );
              const loginButton = screen.getByText(/Logout/i);
              expect(loginButton).toBeInTheDocument();
          });
          test("Make sure Admin Panel Button doesnt show without Role", () => {
              render(
                      <TopNav />
              );
              const adminPanelButton = screen.queryByText(/Admin Panel/i);
              expect(adminPanelButton).toBeNull();
          });
      });
      
      describe("TopNav Component Tests - Admin User", () => {
          beforeEach(() => {
              mockedUseAuth0.mockReturnValue({
                  isAuthenticated: true,
                  user: adminUser,
                  logout: jest.fn(),
                  loginWithRedirect: jest.fn(),
                  getAccessTokenWithPopup: jest.fn(),
                  getAccessTokenSilently: jest.fn(),
                  getIdTokenClaims: jest.fn(),
                  loginWithPopup: jest.fn(),
                  isLoading: false,
              });
          });
          test("Admin Panel Button displays", () => {
              render(
                  <TopNav />
              );
              const adminPanelButton = screen.getByText(/Admin Panel/i);
              expect(adminPanelButton).toBeInTheDocument();
          });
      });
      

      【讨论】:

        猜你喜欢
        • 2020-10-08
        • 2017-10-01
        • 1970-01-01
        • 2017-05-05
        • 2019-09-01
        • 2018-04-25
        • 2018-12-14
        • 1970-01-01
        • 2021-12-10
        相关资源
        最近更新 更多