Jest · fixture · globalSetup
Gerador de CPF em Jest
Setup completo pra usar CPF válido em testes Jest sem gambiarra. Fixture reutilizável, globalSetup pra pré-carregar batch, mock de service que consome CPF, snapshot fixture pra tests determinísticos. Tudo com SDK fakeforge-br.
TL;DR
npm install --save-dev fakeforge-br
// tests/fixtures/cpf.ts
import { FakeForge } from "fakeforge-br"
export const ff = new FakeForge()Free 50 chamadas/dia sem cadastro. Cachea entre testes pra economizar.
Fixture reutilizável
// tests/fixtures/customer-fixture.ts
import { FakeForge } from "fakeforge-br"
const ff = new FakeForge()
// Cachea entre testes pra economizar quota
let cache: string[] | null = null
export async function getCPFs(quantity = 20): Promise<string[]> {
if (!cache || cache.length < quantity) {
cache = await ff.cpf(Math.max(quantity, 50))
}
return cache.slice(0, quantity)
}
export async function getCustomer(): Promise<{
nome: string; cpf: string; email: string; telefone: string
}> {
const [c] = await ff.preset("customer", 1)
return c
}globalSetup: pré-carrega batch
Se muitos testes usam CPF, faz sentido carregar 1 vez no globalSetup e reusar via arquivo:
// jest.config.js
export default {
globalSetup: "./tests/global-setup.ts",
}
// tests/global-setup.ts
import { FakeForge } from "fakeforge-br"
import fs from "fs"
export default async function globalSetup() {
const ff = new FakeForge()
const [cpfs, customers, fintech] = await Promise.all([
ff.cpf(500),
ff.preset("customer", 100),
ff.preset("fintech", 50),
])
fs.writeFileSync(".test-fixtures.json", JSON.stringify({ cpfs, customers, fintech }))
console.log("Loaded fixtures: 500 CPFs + 100 customers + 50 fintech")
}
// tests/setup.ts
import fs from "fs"
const fixtures = JSON.parse(fs.readFileSync(".test-fixtures.json", "utf-8"))
globalThis.testFixtures = fixturesTeste E2E de signup
// tests/signup.test.ts
import { describe, test, expect, beforeAll } from "@jest/globals"
import request from "supertest"
import app from "../src/app"
import { getCPFs } from "./fixtures/customer-fixture"
describe("POST /signup", () => {
let cpfs: string[]
beforeAll(async () => {
cpfs = await getCPFs(10)
})
test.each(cpfs)("aceita CPF válido %s", async (cpf) => {
const res = await request(app).post("/signup").send({
cpf,
email: `user-${Date.now()}@test.com`,
password: "test1234",
})
expect(res.status).toBe(201)
})
test("rejeita CPF inválido", async () => {
const res = await request(app).post("/signup").send({
cpf: "111.111.111-11", // sequência inválida
email: "user@test.com",
})
expect(res.status).toBe(400)
})
})Mock de service que consome CPF
// tests/customer.service.test.ts
import { CustomerService } from "../src/customer.service"
import { getCustomer } from "./fixtures/customer-fixture"
jest.mock("../src/serasa.client", () => ({
consultarScore: jest.fn().mockResolvedValue({ score: 750 }),
}))
describe("CustomerService", () => {
test("cria customer com score do Serasa", async () => {
const dadosFake = await getCustomer()
const service = new CustomerService()
const customer = await service.criar(dadosFake)
expect(customer.cpf).toBe(dadosFake.cpf)
expect(customer.score).toBe(750)
})
})Snapshot fixture determinística
Se você quer testes 100% reprodutíveis (sem chamada API a cada run), gera fixture uma vez e commita:
# scripts/gen-fixtures.js - roda 1 vez, commita output
import { FakeForge } from "fakeforge-br"
import fs from "fs"
const ff = new FakeForge()
const data = {
cpfs: await ff.cpf(100),
customers: await ff.preset("customer", 20),
}
fs.writeFileSync("tests/fixtures/snapshot.json", JSON.stringify(data, null, 2))
// tests/fixture-loader.ts
import snapshot from "./fixtures/snapshot.json"
export const { cpfs, customers } = snapshotTrade-off: fixture fica igual pra sempre (ideal pra snapshot tests) mas não capta bug que só aparece com dado diferente.