首页 > 解决方案 > 如何使用 jest 在 typescript 中模拟外部依赖

问题描述

我绝望地试图在 typescript 中模拟 firebase admin 依赖项以进行单元测试。

我的实际功能如下

import {auth} from 'firebase-admin';

async validateUser(payload: string): Promise<User> {
  try {
    const resp = await auth().verifyIdToken(payload, true);

    return await this.userService.findByUsername(resp.email);
  } catch (e) {
    return null;
 }
}

我试图admin.auth().verifyIdToken(payload, true)通过模拟admin函数来测试。我尝试了如下的测试代码

import {auth} from 'firebase-admin';

jest.mock('firebase-admin');

const mockedAuth = auth as jest.Mock;

mockedAuth.mockReturnValue({
  verifyIdToken: jest.fn().mockResolvedValue(true),
});

但我收到一条错误消息TypeError: Cannot read property 'mockReturnValue' of undefined

如果我理解正确,我会firebase-admin通过调用jest.mock('firebase-admin'). 所以我希望能够在 auth 函数中调用mockReturnValue并再次模拟该verifyIdToken函数。但是,我什至无法打电话mockReturnValue,因为奇怪的是它似乎不存在。

我需要如何编写代码才能模拟解析的值auth().verifyIdToken()

标签: typescriptunit-testingjestjs

解决方案


在这种情况下,问题在于auth类似的导出函数firebase-admin被定义为带有Object.defineProperty. 不幸jest.mock的是,它在评估模块时看不到那些,所以它不会为它们添加模拟。

auth需要在提供给jest.mock. 以下是如何替换jest.mock第二个代码段中的行:

jest.mock('firebase-admin', () =>
{
  const module = jest.createMockFromModule<any>('firebase-admin').default;
  module.auth = jest.fn();
  return module;
});

您还可以选择在该工厂中模拟auth的返回值,以进一步简化您的代码。


推荐阅读