首页 > 解决方案 > Hook 不会被适当地嘲笑 Jest

问题描述

在过去的 2 个小时里,我阅读了无数来自 StackOverflow、medium 和其他独立博客的帖子,但我无法破解或破译如何正确模拟一个简单的自定义useAuth()钩子。

我越来越:

[TypeError:无法解构'(0,_auth.useAuth)(...)'的属性'user',因为它是未定义的。]

这是我的代码:

<Dashboard/>包含useAuth()钩子的组件。(因简洁省略代码)

import { useAuth } from '../../../auth';

export const Dashboard: React.FC<RouteComponentProps> = (props) => {
   const { user } = useAuth();

dashboard.test.tesx文件。

import { render, waitFor } from "../../../__tests_setup__/app-test-utils";
// Sets Up useAuth
import { mockPatientDetails } from "../../../setupTestPatient";
import { mockBaseAuth } from "../../../setupTestShared";
import { Dashboard } from "./index";

import { useAuth } from "../../../auth";

jest.mock("../../../auth");

describe("Tests the Patient's dashboard", () => {
  beforeAll(() => {
    (useAuth as any).mockReturnValue({
      ...mockBaseAuth,
      user: {
        ...mockBaseAuth.user,
        profile: mockPatientDetails.profile,
        profile_id: mockPatientDetails.profile_id,
        username: mockPatientDetails.username,
      },
    });
  });
  it("Will be able to assign a consultation now", async () => {
    const renderer = await render(<Dashboard />);
    waitFor(async () => {
      await expect(renderer.getByText(`Hola ${mockPatientDetails.username}`));
    });
    expect(true).toBe(true);
  });
});

尝试了其他变体:

import { render, waitFor } from "../../../__tests_setup__/app-test-utils";
// Sets Up useAuth
import { mockPatientDetails } from "../../../setupTestPatient";
import { mockBaseAuth } from "../../../setupTestShared";
import { Dashboard } from "./index";

import { useAuth } from "../../../auth";


// Variation 1
import * as auth from '../../../auth'
jest.spyOn(auth, "useAuth").mockImplementation(() => ({
  ...mockBaseAuth,
  user: {
    ...mockBaseAuth.user,
    profile: mockPatientDetails.profile,
    profile_id: mockPatientDetails.profile_id,
    username: mockPatientDetails.username,
  },
}));

// Variation 2
jest.mock("../../../auth/index", () => ({
  __esModule: true,
  useAuth: jest.fn(() => ({
    ...mockBaseAuth,
    user: {
      ...mockBaseAuth.user,
      profile: mockPatientDetails.profile,
      profile_id: mockPatientDetails.profile_id,
      username: mockPatientDetails.username,
    },
  })),
}));
// Variation 3
There have been many other variations which I haven't included as I've completely forgotten about them.

这是我的文件夹结构,以防万一。

文件夹结构

PS:这里是上面显示的变量:

src/setupTestShared.ts
import { GENDER, InteractionMedias, UserProfile } from "./@dts";
import { useAuth } from "./auth";

const success = Promise.resolve({
  type: "success" as const,
  result: true,
});

export const mockBaseAuth: ReturnType<typeof useAuth> = {
  login(u: string, p: string) {
    return success;
  },
  authenticated: true,
  logout() {},
  register(p: UserProfile, pass: string) {
    return success;
  },
  userExists(u: string) {
    return Promise.resolve("USER_REGISTERED" as const);
  },
  user: {
    date_of_birth: "1990-12-21",
    email: "test@gmail.com",
    emails: ["test@gmail.com"],
    first_name: "Maria",
    gender: GENDER.FEMALE,
    id: 1,
    identification_id: "402-2066666-1",
    interaction_media_preferred: InteractionMedias.VIDEO,
    last_name: "Anabelle",
    loggedInDate: new Date(),
    phones: ["809-544-5111"],
    profile: "ANONYMOUS",
    profile_id: 1,
    username: "anonymous",
  },
};
export const mockPatientDetails = {
  username: "PAC123456",
  profile: "patient" as const,
  profile_id: 2,
};

会是什么呢?

标签: reactjstypescriptunit-testingjestjsreact-testing-library

解决方案


它现在正在工作!

这个答案帮助了我: https ://stackoverflow.com/a/60282832/1057052

// https://stackoverflow.com/a/60282832/1057052
jest.mock("../../../auth", () => ({
 // this isn't needed -  __esModule: true,
  useAuth: () => ({
    ...mockBaseAuth,
    user: {
      ...mockBaseAuth.user,
      profile: mockPatientDetails.profile,
      profile_id: mockPatientDetails.profile_id,
      username: mockPatientDetails.username,
    },
  }),
}));

诀窍不是将 分配jest.fn()useAuth()。


推荐阅读