开发者问题收集

开玩笑,如何模拟对象内部的函数?

2021-09-08
2125

我有一个函数将调用 Firebase 和 getIdToken 函数

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

如何模拟此行代码?

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

详情:

getAuth() 是一种将从 Firebase 返回 Auth 对象的方法。

currentUser 是来自 Auth 对象的属性,具有 User 类型。

getIdToken() 是来自 currentUser 的一种方法,它将返回 Promise<string>

因此,这就是我尝试的。

我尝试过的:

我在测试文件的开头模拟了 getAuth()getAuth() 是一个函数, jest.fn() 也是。

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

然后在我的一个测试用例中,我尝试了这个:

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

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

    // other stuff here
}

如您所见,我模拟了 getAuth() 函数以返回 currentUser 对象。然后 getIdToken() 函数位于 currentUser 对象内,该对象将返回一个字符串。

但是当我运行测试时,我收到此错误:

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

它指出 currentUser 未定义。但是由于我在测试开始时使用了 mockResolvedValueOnce ,但仍然无法获取 currentUser 值。

问题

我该如何模拟这个函数?我做错了什么?

const firebaseToken = getAuth().currentUser?.getIdToken();
2个回答

这对我有用:

const getAuth = jest.fn(() => ({
  currentUser: {
    getIdToken: () => 32,
  }
}));
alextrastero
2021-09-08

最后我像这样模拟它:

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

其中 getAuth 将返回一个 currentUser 对象,在 currentUser 对象内部有一个 getIdToken 函数,它将返回“abc”作为值。

然后当“在我的实际代码文件中”像这样调用时:

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

但是“测试文件”中收到的 firebaseToken 的值将是 abc ,因为我们已经模拟了上面的值。在测试文件中,它不会调用实际的 Firebase 方法,而是会调用我上面模拟的方法并获取返回值。

ken
2021-09-11