ken
ken

Reputation: 2682

Jest, How to mock a function inside an object?

I have an function that will call to Firebase and getIdToken function

export const getUserFromDb = async () => {
  const path = "/user";
  const firebaseToken = getAuth().currentUser?.getIdToken(); // here need to get it
  
  console.log(firebaseToken)
  const myInit = {
    headers: {
      Authorization: `token ${firebaseToken}`,
    },
  };

  return API.get(path, myInit);
};

How can I mock this line of code?

const firebaseToken = getAuth().currentUser?.getIdToken();

For details:

getAuth() is a method which will return a Auth object from Firebase.

currentUser is a property from Auth object, with User type.

getIdToken() is a method from currentUser, which will return Promise<string>

Therefore this is what I tried.

What I have tried:

I have mock getAuth() at the beginning of test file, getAuth() is a function, so is jest.fn().

jest.mock("firebase/auth", () => { return { getAuth: jest.fn() } }

Then in one of my Test case, I tried this:

it("should login success and setUser", async () => {

    (getAuth as jest.Mock).mockResolvedValueOnce({
        currentUser: {
            getIdToken: jest.fn().mockReturnValueOnce('abc')
        }
    })

    // other stuff here
}

As you can see, I mock getAuth() function to return a currentUser object. Then getIdToken() function is inside currentUser object which will return a string.

But when I run the test, I get this error:

console.log TypeError: Cannot read property 'currentUser' of undefined

It stated that currentUser is undefined. But since I mockResolvedValueOnce at the beginning of the test, but it still cant get the currentUser value.

Question

How can I mock this function? And what I doing wrong?

const firebaseToken = getAuth().currentUser?.getIdToken();

Upvotes: 2

Views: 2407

Answers (2)

ken
ken

Reputation: 2682

End up I mock it like this:

(getAuth as jest.Mock).mockReturnValue({
      currentUser: {
        getIdToken: jest.fn().mockReturnValueOnce("abc"),
      },
    });

Which is getAuth will return a currentUser object, inside currentUser object have a getIdToken function which will return "abc" as value.

Then when "in my actual code file" called like this:

const firebaseToken = getAuth().currentUser?.getIdToken();

But the value of firebaseToken received in "Test file" will be abc, since we already mock the value above. In test file, it wont call to actual Firebase method, instead it will call to the method I mocked above and get the value back.

Upvotes: 0

alextrastero
alextrastero

Reputation: 4300

This worked for me:

const getAuth = jest.fn(() => ({
  currentUser: {
    getIdToken: () => 32,
  }
}));

Upvotes: 0

Related Questions