Javascript React:如何使用Jest模拟Auth0进行测试
我正在使用React(React创建应用程序和TypeScript)。使用Auth0登录 我想用Jest编写测试,我发现这个ressource基本上是唯一一个关于模拟Auth0对象的东西 因此,我的代码如下所示:Javascript React:如何使用Jest模拟Auth0进行测试,javascript,reactjs,typescript,jestjs,auth0,Javascript,Reactjs,Typescript,Jestjs,Auth0,我正在使用React(React创建应用程序和TypeScript)。使用Auth0登录 我想用Jest编写测试,我发现这个ressource基本上是唯一一个关于模拟Auth0对象的东西 因此,我的代码如下所示: 从“React”导入React; 从“react dom”导入react dom; 从“/index”导入顶栏; 进口{ useAuth0 }来自“react-auth0-spa”; 常量用户={ 电子邮件:“johndoe@me.com", 已验证的电子邮件:正确, sub:“go
从“React”导入React;
从“react dom”导入react dom;
从“/index”导入顶栏;
进口{
useAuth0
}来自“react-auth0-spa”;
常量用户={
电子邮件:“johndoe@me.com",
已验证的电子邮件:正确,
sub:“google-oauth2 | 1234567890134”
};
//截取useAuth0函数并模拟它
笑话模拟(“react-auth0-spa”);
描述(“第一次测试”,()=>{
在每个之前(()=>{
//模拟Auth0钩子并使其返回登录状态
useAuth0.mockReturnValue({
我证实:是的,
用户,
注销:jest.fn(),
loginWithRedirect:jest.fn()
});
});
它(“渲染而不崩溃”,()=>{
const div=document.createElement(“div”);
ReactDOM.render( ,div);
});
});代码>这是一个打字脚本错误。您需要键入模拟的useAuth0
,因为原始类型没有名为mockReturnValue
的方法。像这样的方法应该会奏效:
const mockedUseAuth0 = <jest.Mock<typeof useAuth0>>useAuth0;
mockedUseAuth0.mockReturnValue({
isAuthenticated: true,
user,
logout: jest.fn(),
loginWithRedirect: jest.fn()
});
const mockedUseAuth0=useAuth0;
mockedUseAuth0.mockeReturnValue({
我证实:是的,
用户,
注销:jest.fn(),
loginWithRedirect:jest.fn()
});
我自己花了一个小时左右的时间来解决这个问题。问题源于修改模拟返回值后应用于useAuth0的不正确类型。我的解决方案是使用来自“ts jest/utils”的mock。您还可以向用户对象添加角色、范围等。(请参阅adminUser对象)
从“@testing library/react”导入{render,screen}”;
从“@auth0/auth0”导入{useAuth0}”;
从“ts jest/utils”导入{mocked};
常量用户={
电子邮件:“johndoe@me.com",
已验证的电子邮件:正确,
sub:“google-oauth2 | 12345678901344”,
};
常量adminUser={
电子邮件:“johndoe@me.com",
已验证的电子邮件:正确,
sub:“google-oauth2 | 12345678901344”,
"https:///roles“:[“管理员”,“超级用户”],
};
开玩笑的模仿(“@auth0/auth0 react”);
const mockedUseAuth0=mocked(useAuth0,true);
描述(“TopNav组件测试-已登录)”,()=>{
在每个之前(()=>{
mockedUseAuth0.mockeReturnValue({
我证实:是的,
用户,
注销:jest.fn(),
loginWithRedirect:jest.fn(),
getAccessTokenWithPopup:jest.fn(),
getAccessTokenSilently:jest.fn(),
getIdTokenClaims:jest.fn(),
loginWithPopup:jest.fn(),
孤岛加载:false,
});
});
测试(“登录时显示注销按钮”,()=>{
渲染(
);
const loginButton=screen.getByText(/Logout/i);
expect(loginButton).toBeInTheDocument();
});
测试(“确保没有角色时管理面板按钮不会显示”,()=>{
渲染(
);
const adminPanelButton=screen.queryByText(/Admin Panel/i);
expect(adminPanelButton.toBeNull();
});
});
描述(“TopNav组件测试-管理员用户”,()=>{
在每个之前(()=>{
mockedUseAuth0.mockeReturnValue({
我证实:是的,
用户:adminUser,
注销:jest.fn(),
loginWithRedirect:jest.fn(),
getAccessTokenWithPopup:jest.fn(),
getAccessTokenSilently:jest.fn(),
getIdTokenClaims:jest.fn(),
loginWithPopup:jest.fn(),
孤岛加载:false,
});
});
测试(“管理面板按钮显示”,()=>{
渲染(
);
const adminPanelButton=screen.getByText(/Admin Panel/i);
expect(adminPanelButton).toBeInTheDocument();
});
});
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();
});
});