0

For the last 2 hours, I've read unnumerous posts from StackOverflow, medium, and other independent blogs, and I haven't been able to crack or decipher how to properly mock a simple custom useAuth() hook.

I'm getting:

[TypeError: Cannot destructure property 'user' of '(0 , _auth.useAuth)(...)' as it is undefined.]

Here's my code:

The <Dashboard/> component which includes the useAuth() hook. (Code omitted due to brevity)

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

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

The dashboard.test.tesx file.

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);
  });
});

Other variations tried:

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.

Here's my folder structure, just in case.

Folder structure

P.S: Here are the variables shown above:

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,
};

What could it be?

Jose A
  • 10,053
  • 11
  • 75
  • 108

1 Answers1

3

It's working now!

This answer helped me: 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,
    },
  }),
}));

The trick was not assigning the jest.fn() to the useAuth().

halfer
  • 19,824
  • 17
  • 99
  • 186
Jose A
  • 10,053
  • 11
  • 75
  • 108