はじめに
@firebase/rules-unit-testing
を使って、セキュリティルールをテストするためのコードを書いていました。
その時に書いていたコードの内容は次の内容です。
import "jest";
import * as fs from "fs";
import {
initializeTestEnvironment,
RulesTestContext,
RulesTestEnvironment,
} from "@firebase/rules-unit-testing";
import {
doc,
} from "firebase/firestore";
import { v4 as uuidv4 } from "uuid";
describe("テスト /users", () => {
let testEnv: RulesTestEnvironment;
let user: RulesTestContext;
const projectId = uuidv4();
const uid = uuidv4();
beforeAll(async () => {
testEnv = await initializeTestEnvironment({
projectId: projectId,
firestore: {
rules: fs.readFileSync("../firestore.rules", "utf8"),
},
});
user = testEnv.authenticatedContext(uid, {});
// ...
});
afterAll(async () => {
testEnv.cleanup();
});
it("テスト1", async () => {
const ref = doc(user.firestore(), "users", uid);
// ...
});
it("テスト2", async () => {
const ref = doc(user.firestore(), "users", uid);
// ...
});
});
テストを実行してみると、2番目に実行されたテストが失敗していました。
テスト /users
✓ テスト1 (97 ms)
✕ テスト2 (129 ms)
しかし、テスト2のみを実行してみるとテストは通りました。
エラーの内容
発生したエラーの内容は次の内容です。
FirebaseError: Firestore has already been started and its settings can no longer be changed. You can only modify settings before calling any other methods on a Firestore object.
エラーの原因
色々試していくと、上記のエラーが発生した原因は次のコードにあることがわかりました。
let user: RulesTestContext;
const uid = uuidv4();
// ...
beforeAll(async () => {
// ...
user = testEnv.authenticatedContext(uid, {});
// ...
});
it("テスト1", async () => {
const ref = doc(user.firestore(), "users", uid);
// ...
});
it("テスト2", async () => {
const ref = doc(user.firestore(), "users", uid);
// ...
});
共通のRulesTestContext
をテストケースごとに使い回して、user.firestore()
をその度に呼び出していたことが上記のエラーが発生した原因であることが判明しました。
解決方法
そこで、authenticatedContext()
の呼び出しをテストケースごとに行い、使い回しをやめることにしました。
it("テスト1", async () => {
const user = testEnv.authenticatedContext(uid, {});
const ref = doc(user.firestore(), "users", uid);
// ...
});
it("テスト2", async () => {
const user = testEnv.authenticatedContext(uid, {});
const ref = doc(user.firestore(), "users", uid);
// ...
});
結果、以前のコードで発生していたエラーは解消されました。