← Back to list

firebase-testing
by janisto
Fastify playground
⭐ 0🍴 0📅 Jan 25, 2026
SKILL.md
name: firebase-testing description: Guide for testing Firebase Admin SDK with Vitest mocks. Use when writing tests that involve Firebase Auth, Firestore, or Firebase App.
Firebase Testing Patterns
This skill provides patterns for mocking Firebase Admin SDK in Vitest tests.
Mock Helpers Location
Firebase mocks are located in app/tests/mocks/firebase.ts and provide:
createFirebaseAppMock()- Mock Firebase App instancecreateFirebaseAuthMock()- Mock Firebase Auth with verifyIdToken, getUsercreateFirestoreMock()- Mock Firestore with collection, doc, getresetFirebaseMocks()- Reset all mocks between tests
Firebase Plugin Test Template
import Fastify from "fastify";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import {
createFirebaseAppMock,
createFirebaseAuthMock,
createFirestoreMock,
} from "../../mocks/firebase.js";
const mockApp = createFirebaseAppMock();
const mockAuth = createFirebaseAuthMock();
const mockFirestore = createFirestoreMock();
vi.mock("firebase-admin/app", () => ({
getApps: vi.fn(() => [mockApp]),
initializeApp: vi.fn(() => mockApp),
cert: vi.fn(),
}));
vi.mock("firebase-admin/auth", () => ({
getAuth: vi.fn(() => mockAuth),
}));
vi.mock("firebase-admin/firestore", () => ({
getFirestore: vi.fn(() => mockFirestore),
}));
describe("Firebase Plugin", () => {
beforeEach(() => {
vi.clearAllMocks();
});
afterEach(async () => {
// Clear module cache so dynamic imports get fresh mocked modules
vi.resetModules();
});
it("should register firebase decorator", async () => {
const { default: firebasePlugin } = await import(
"../../../src/plugins/firebase.js"
);
const fastify = Fastify();
await fastify.register(firebasePlugin);
await fastify.ready();
expect(fastify.firebase).toBeDefined();
await fastify.close();
});
});
Auth Testing Patterns
Valid Token Authentication
it("should authenticate with valid token", async () => {
const mockDecodedToken = {
uid: "test-user-123",
email: "test@example.com",
email_verified: true,
};
mockAuth.verifyIdToken.mockResolvedValue(mockDecodedToken);
const response = await fastify.inject({
method: "GET",
url: "/protected",
headers: { authorization: "Bearer valid-token" },
});
expect(response.statusCode).toBe(200);
expect(mockAuth.verifyIdToken).toHaveBeenCalledWith("valid-token", false);
});
Invalid Token Handling
it("should return 401 for invalid token", async () => {
mockAuth.verifyIdToken.mockRejectedValue(
new Error("Firebase ID token has invalid signature"),
);
const response = await fastify.inject({
method: "GET",
url: "/protected",
headers: { authorization: "Bearer invalid-token" },
});
expect(response.statusCode).toBe(401);
});
Token Revocation
it("should return 401 when token is revoked", async () => {
const revokedError = Object.assign(new Error("Token has been revoked"), {
code: "auth/id-token-revoked",
});
mockAuth.verifyIdToken.mockRejectedValue(revokedError);
const response = await fastify.inject({
method: "GET",
url: "/protected",
headers: { authorization: "Bearer revoked-token" },
});
expect(response.statusCode).toBe(401);
expect(response.json().message).toContain("Token has been revoked");
});
Missing Authorization Header
it("should return 401 when no authorization header", async () => {
const response = await fastify.inject({
method: "GET",
url: "/protected",
});
expect(response.statusCode).toBe(401);
});
Firestore Testing Patterns
Mocking Collection Queries
it("should query Firestore collection", async () => {
const mockDocs = [
{ id: "doc1", data: () => ({ name: "Test 1" }) },
{ id: "doc2", data: () => ({ name: "Test 2" }) },
];
mockFirestore.collection.mockReturnValue({
get: vi.fn().mockResolvedValue({ docs: mockDocs }),
limit: vi.fn().mockReturnThis(),
});
// Test code that queries Firestore
});
Mocking Document Operations
it("should get a document", async () => {
const mockDoc = {
exists: true,
id: "doc-id",
data: () => ({ field: "value" }),
};
mockFirestore.collection.mockReturnValue({
doc: vi.fn().mockReturnValue({
get: vi.fn().mockResolvedValue(mockDoc),
}),
});
// Test code that gets a document
});
Key Patterns
- Mock before import: Use
vi.mock()at module level before importing tested modules - Dynamic imports: Use
await import()after mocks are set up to ensure mocks are applied - Reset between tests:
vi.clearAllMocks()in beforeEach - clears mock call historyvi.resetModules()in afterEach - clears module cache so dynamic imports get fresh mocked modules
- Realistic data: Use realistic mock data that matches Firebase structures
Commands
cd app
npm run test # Run all tests
npm run test:coverage # Run tests with coverage
Boundaries
- Never use real Firebase credentials in tests
- Always mock Firebase Admin SDK modules
- Use the shared mock helpers from
tests/mocks/firebase.ts
Score
Total Score
60/100
Based on repository quality metrics
✓SKILL.md
SKILL.mdファイルが含まれている
+20
✓LICENSE
ライセンスが設定されている
+10
○説明文
100文字以上の説明がある
0/10
○人気
GitHub Stars 100以上
0/15
○最近の活動
3ヶ月以内に更新がある
0/10
○フォーク
10回以上フォークされている
0/5
✓Issue管理
オープンIssueが50未満
+5
✓言語
プログラミング言語が設定されている
+5
○タグ
1つ以上のタグが設定されている
0/5
Reviews
💬
Reviews coming soon