【问题标题】:Firebase Initialization failure in jest test开玩笑测试中的 Firebase 初始化失败
【发布时间】:2021-06-26 15:17:51
【问题描述】:

我正在为slack bolt 应用程序的事件处理程序编写一些测试。昨天我为我所有的事件处理程序编写了一整套测试,它们都完美通过了,生活很美好。然后,我做了一些重构,现在我的整个套件甚至无法运行,相反,我只看到错误提示 firebase 无法初始化。

Firebase 无法初始化,因为 jest 没有正确初始化 firebase 所需的环境变量。但是,我当然不希望它初始化。而昨天,它不是。因此,我试图弄清楚为什么它在现在运行测试时尝试初始化 firebase,而以前似乎没有。

我在Events.test.ts 中进行的最简单的测试只是测试Events.ts 中的handleBlockActions 函数,它只是确认一个松弛事件。这个测试工作得很好,直到有一个函数Event.ts 进行数据库调用。即使我没有将handleTeamRename 导入Events.test.ts,如果我在Events.ts 中有该功能,测试将失败并显示如下firebase 消息。如果我将调用updateOrganizationName 的行注释掉,则测试通过。

我不明白为什么仅仅拥有一个在我从中导入其他东西的文件中调用数据库的函数就足以使我的测试由于firebase而失败未能正确初始化。

我正在尝试制作一个最小的示例;原始文件中有更多的功能,但我已经复制并删除了所有我能用最少的代码重现问题的东西。

如果有人能帮助我理解 jest 在做什么,为什么它试图初始化 firebase,尽管据我所知,我没有要求它,以及我如何更好地处理这种情况,我将不胜感激。

我能找到的大多数其他答案都是关于更普遍地模拟 firebase,如果我现在可以的话,我想避免这种情况 - 鉴于昨天它似乎工作,这似乎是可能的?

文件结构

- database
    - Organizations.ts
    - Slack.ts
    - firebase.ts
- services
    - Events.test.ts
    - Events.ts
// Events.ts

import { AckFn, DialogValidation, SayArguments } from "@slack/bolt";
import { updateOrganizationName } from "../database/Organizations";
import { getSlackTeam } from "../database/Slack";

export type AckFnSig =
  | AckFn<void>
  | AckFn<string | SayArguments>
  | AckFn<DialogValidation>;

/**
 * A user renames the organization name in slack
 */
export const handleTeamRename = async (
  userId: string,
  token: string
): Promise<void> => {
  try {
    const team = await getSlackTeam(token, userId);
    // if I comment out this line, the test passes
    await updateOrganizationName(team.id, team.name, team.icon.image_230);
  } catch (e) {
    console.error("team_rename event");
    console.error(e);
  }
};

/**
 * Acknowledge user clicking on action button
 */
export const handleBlockActions = async (ack: AckFnSig): Promise<void> => {
  try {
    ack();
  } catch (e) {
    console.error("action_link_accounts event");
    console.error(e);
  }
};
// Events.test.ts

import { AckFnSig, handleBlockActions } from "./Events";

describe("events", () => {
  describe("handleBlockActions", () => {
    it("should ack block actions", async () => {
      const mockAck = jest.fn();

      void (await handleBlockActions(
        (mockAck as unknown) as AckFnSig
      ));

      await expect(mockAck).toHaveBeenCalledTimes(1);
    });
  });
});
 FAIL  src/services/Events.test.ts
  ● Test suite failed to run

    Service account object must contain a string "project_id" property.

       8 | admin.initializeApp({
       9 |   // current required type appears to be wrong so has to be cast as any
    > 10 |   credential: admin.credential.cert(firebaseServiceKey as any),
         |                                ^
      11 |   databaseURL:
      12 |     process.env.FIREBASE_URL || "[my firebase url]",
      13 | });

      at FirebaseAppError.FirebaseError [as constructor] (node_modules/firebase-admin/lib/utils/error.js:44:28)
      at FirebaseAppError.PrefixedFirebaseError [as constructor] (node_modules/firebase-admin/lib/utils/error.js:90:28)
      at new FirebaseAppError (node_modules/firebase-admin/lib/utils/error.js:125:28)
      at new ServiceAccount (node_modules/firebase-admin/lib/credential/credential-internal.js:134:19)
      at new ServiceAccountCredential (node_modules/firebase-admin/lib/credential/credential-internal.js:68:15)
      at Object.<anonymous>.exports.cert (node_modules/firebase-admin/lib/credential/credential.js:34:54)
      at Object.<anonymous> (src/database/firebase.ts:10:32)

【问题讨论】:

    标签: typescript firebase jestjs slack-api firebase-admin


    【解决方案1】:

    这是昨天工作的,因为事件处理程序曾经位于从index.ts 导入app 的文件中。这个文件加载了env,因此 jest 能够初始化 firebase - 尽管我不认为它是 - 所以它没有抱怨任何数据库功能。

    所以,为了解决这个问题,我将考虑更好地处理我的环境变量,然后看看如何正确地模拟 firebase。

    【讨论】:

      猜你喜欢
      • 2018-02-13
      • 2017-11-19
      • 2021-01-23
      • 2020-10-08
      • 2017-08-28
      • 2018-07-20
      • 2020-08-19
      • 2021-05-02
      • 2017-02-11
      相关资源
      最近更新 更多