What it does
Prevents the agent from using Bun’s mock.module API in tests. mock.module mutates the global module registry for the entire test process — once one test mocks node:fs, every subsequent test sees the mock until the process exits. This causes flaky CI, order-dependent failures, and “works locally” bugs that are nightmares to debug.
The skill teaches the agent to refactor toward factory functions and dependency injection instead, which keep mocks scoped to a single test.
When to use it
- Any Bun project with a non-trivial test suite
- After you’ve been bitten by a CI failure that disappeared when tests ran in isolation
- During code review of agent-generated tests
- When migrating from Jest (where
jest.mockis well-isolated) to Bun
How it works
Add to your CLAUDE.md:
## Testing — No mock.module
Bun's `mock.module` poisons the module registry globally and has caused
repeated CI failures. Use factory + dependency injection patterns instead.
If you encounter existing `mock.module` usage while working on adjacent code,
flag it as a refactor candidate rather than extending the pattern.
The pattern to use instead
Bad — uses mock.module (poisons global registry):
import { mock } from "bun:test";
mock.module("./email-client", () => ({
sendEmail: () => Promise.resolve({ id: "fake" }),
}));
import { signupHandler } from "./signup";
test("signup sends welcome email", async () => {
await signupHandler({ email: "test@example.com" });
// mock leaks into every other test in the process
});
Good — factory + DI (mock scoped to one test):
// signup.ts
export function makeSignupHandler(deps: { sendEmail: SendEmail }) {
return async (input: SignupInput) => {
// ...
await deps.sendEmail({ to: input.email, template: "welcome" });
};
}
// signup.test.ts
test("signup sends welcome email", async () => {
const sendEmail = mock(() => Promise.resolve({ id: "fake" }));
const handler = makeSignupHandler({ sendEmail });
await handler({ email: "test@example.com" });
expect(sendEmail).toHaveBeenCalledWith({
to: "test@example.com",
template: "welcome",
});
});
Why it matters
Mock isolation is a property of the test framework. Bun chose to make mock.module process-global rather than file-scoped, which is a footgun for any non-trivial codebase. Factory + DI is more verbose at the call site, but it makes dependencies explicit, keeps mocks scoped, and works in any test runner — including future migrations away from Bun.