React:如何模拟 Auth0 以使用 Jest 进行测试
Posted
技术标签:
【中文标题】React:如何模拟 Auth0 以使用 Jest 进行测试【英文标题】:React: How to mock Auth0 for testing with 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 '() => IAuth0Context | undefined'.ts(2339)
我有点迷路了,任何帮助将不胜感激!
【问题讨论】:
【参考方案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();
);
);
【讨论】:
以上是关于React:如何模拟 Auth0 以使用 Jest 进行测试的主要内容,如果未能解决你的问题,请参考以下文章
如何模拟在使用 Jest 测试的 React 组件中进行的 API 调用
如何使用 jest 模拟 react-router-dom 的 BrowserRouter
React Jest:如何模拟返回数据的异步 API 调用?