【问题标题】:How to inject data imported by Firestore emulator into db instance如何将 Firestore 模拟器导入的数据注入数据库实例
【发布时间】:2020-07-22 21:01:47
【问题描述】:

我知道我们现在可以使用 Firestore 模拟器export and import data

如何在单元测试环境中访问导入的数据?也就是说,当使用@firebase/testing 时,我们通常会这样创建测试应用:

const db = firebase.initializeTestApp({ projectId: PROJECT_ID, auth}).firestore(); 

如何访问通过模拟器导入的数据并将其馈送到此数据库实例中?

我的用例是针对导入的数据对 firestore 规则运行单元测试(作为参考,所需的设置与其他 related question 非常相似,但我不依赖手动构建的模拟对象,而是使用来自模拟器导出/导入功能的数据)

这是我的测试文件

/**
 * unit tests for firestore security and data validation rules
 *
 * adapted from https://github.com/firebase/quickstart-testing/blob/master/unit-test-security-rules
 */
const firebase = require("@firebase/testing");
const fs = require("fs");
const path = require("path")

/**
 * The emulator will accept any project ID for testing.
 */
const PROJECT_ID = "test-dev-project";

/**
 * The FIRESTORE_EMULATOR_HOST environment variable is set automatically
 * by "firebase emulators:exec"
 */
const COVERAGE_URL = `http://${process.env.FIRESTORE_EMULATOR_HOST}/emulator/v1/projects/${PROJECT_ID}:ruleCoverage.html`;

/**
 * Set up mock data
 */
const mockUser = {
  uid: 'alice',
  email: 'alice@example.com',
  company: 'testCompany'
}

/**
 * Creates a new client FirebaseApp with authentication and returns the Firestore db instance.
 * @param {object} auth the object to use for authentication (typically {uid: some-uid})
 * @param {object} data the test data to use for filling the db
 * @return {object} the firestore instance db .
 */
getAuthedDb = async (auth, data) => {
  // initialize test app
  const app = firebase.initializeTestApp({ projectId: PROJECT_ID, auth });
  let db = app.firestore();
  return db;
};

beforeEach(async () => {
  // Clear the database between tests
  await firebase.clearFirestoreData({ projectId: PROJECT_ID });
});

before(async () => {
  // Load the rules file before the tests begin
  const rules = fs.readFileSync("firestore.rules", "utf8");
  await firebase.loadFirestoreRules({ projectId: PROJECT_ID, rules });
});

after(async () => {
  // Delete all the FirebaseApp instances created during testing
  // Note: this does not affect or clear any data
  await Promise.all(firebase.apps().map((app) => app.delete()));
  console.log(`View rule coverage information at ${COVERAGE_URL}\n`);
});

function printDoc(doc) {
  if (doc.exists) {
      console.log(`Document ${doc.id} data:`, doc.data());
  } else {
      // doc.data() will be undefined in this case
      console.log(`No such document: ${doc.ref.path}, parent: ${doc.ref.parent.id}`);
  }
}

describe("Test Security Rules", () => {
  it("fetches data imported from emulator", async () => {
    const db = await getAuthedDb({uid: 'abcd'});
    const ref = db.doc("testdata/ac7yWTZekvGJMQj6Zq3M");
    await firebase.assertSucceeds(ref.get().then(printDoc));
  });
});

当我运行 firebase emulators:exec --only firestore --import=data/ "yarn run test-rules"test-rules 映射到 mocha --timeout 10000 test/test.spec.js)时,断言成功,但找不到文档 "testdata/ac7yWTZekvGJMQj6Zq3M",但它存在于我从 data/ 导入的数据中

【问题讨论】:

    标签: firebase unit-testing google-cloud-firestore firebase-tools


    【解决方案1】:

    原来这是问题所在:

    beforeEach(async () => {
      // Clear the database between tests
      await firebase.clearFirestoreData({ projectId: PROJECT_ID });
    });
    

    在执行每个测试之前,它会完全清除模拟器数据。我犯了一个大错误,解决方案是完全删除该代码,因为我的测试数据不需要在测试用例之间更改

    【讨论】:

      猜你喜欢
      • 2020-01-10
      • 2021-05-13
      • 1970-01-01
      • 2020-05-17
      • 2012-07-28
      • 1970-01-01
      • 1970-01-01
      • 2019-10-17
      • 2014-04-07
      相关资源
      最近更新 更多