如何在集成测试中重置firestore模拟器

the*_*ing 14 dart firebase flutter google-cloud-firestore firebase-cli

我正在使用 firestore 模拟器在 flutter 和 dart 中运行集成测试。首先,我使用一些数据启动 firestore 模拟器,如下所示:firebase emulators:start --import=./dir.

然后我启动一个 android 模拟器并启动我想在 android 模拟器上测试的应用程序。该应用程序配置为使用 firestore 模拟器。然后我运行一系列测试,所有测试都写入 firestore 模拟器。

但在每次测试开始时,我希望将数据重置为我第一次启动模拟器时的状态。例如,如果测试按以下顺序执行:

测试 A 测试 B 测试 C

当执行测试 B 和 C 时,我不想让创建的测试 A 的数据出现在数据库中。我可以终止 firestore 模拟器并在每次测试开始时再次启动它。但这会让我的测试变慢很多。

您知道 Firebase 模拟器中存在的重置数据的方法吗?

小智 7

当您说要“重置数据”时,我假设您指的是 firestore。

根据https://firebase.google.com/docs/emulator-suite/install_and_configure#use_the_emulator_hub_rest_api上的文档

import fetch from 'node-fetch';

import firebaseConfig from '../../../firebase.json';
const hubEmulatorPort = firebaseConfig.emulators.hub.port;
const firestoreEmulatorPort = firebaseConfig.emulators.firestore.port;

async function clearDb() {
  const response = await fetch(
    `http://localhost:${firestoreEmulatorPort}/emulator/v1/projects/${process.env.PROJECT_ID}/databases/(default)/documents`,
    {
      method: 'DELETE',
    }
  );
  if (response.status !== 200) {
    throw new Error('Trouble clearing Emulator: ' + (await response.text()));
  }
}

async function populateDb(data) {
  // Logic for adding in any data you want in the db
  // before each test run
}

async function enableBackgroundTriggers() {
  const response = await fetch(`http://localhost:${hubEmulatorPort}/functions/enableBackgroundTriggers`, {
    method: 'PUT',
  });
  if (response.status !== 200) {
    throw new Error('Trouble enabling database triggers in emulator: ' + (await response.text()));
  }
}

async function disableBackgroundTriggers() {
  const response = await fetch(`http://localhost:${hubEmulatorPort}/functions/disableBackgroundTriggers`, {
    method: 'PUT',
  });
  if (response.status !== 200) {
    throw new Error('Trouble disabling database triggers in emulator: ' + (await response.text()));
  }
}

async function resetDb(data) {
  await disableBackgroundTriggers();
  await clearDb();
  await populateDb(data);
  await enableBackgroundTriggers();
}

export { resetDb };
Run Code Online (Sandbox Code Playgroud)

我找不到清除数据库的来源,但是clearDb 中的RESTful 调用可以满足您的要求。

在清除或填充数据库之前禁用触发器非常重要,以防您的 Firestore 触发器以测试不期望的方式修改数据。我通过将完整的数据库状态传递给 populateDb 方法来编写测试,然后在运行测试之前重新启用触发器,以便我可以测试所述触发器。如果您没有运行任何 firestore 触发器,则仅clearDb 调用就足以满足您的目的。

我的测试都在我的 beforeEach 挂钩中调用了 resetDb() ,以确保每个测试的干净运行。我建议将其添加到您最喜欢的测试 API 公开的任何类似“beforeEach”的挂钩中。

如果您的测试执行诸如在 Firebase 身份验证中创建用户之类的操作,则您必须找到另一种方法在测试运行之间清除它们。

如果有人可以找到有关如何清除 Firebase 模拟器套件中其他模拟器的文档,请将其放在评论中。我目前正在尝试找到一种清除身份验证模拟器的方法,这实际上就是我发现这个问题的方法。

祝你好运!