bun-mock-extended: Evaluation & Decision
TL;DR
Decision: Don’t use bun-mock-extended. Use raw bun:test mocks instead.
The library has too many broken features, and its main benefit (type safety) doesn’t provide meaningful value in a workflow where tests are run frequently.
Issues Discovered
1. mockDeep Doesn’t Work with NestJS
// ❌ FAILS: "Expected this to be instanceof Mock"const mockManifest = mockDeep<ManifestService>();NestJS @Injectable() decorated classes cause mockDeep to fail entirely.
2. calledWith Has Multiple Problems
No asymmetric matcher support:
// ❌ FAILS - returns undefinedmock.process.calledWith("a", expect.any(String)).mockReturnValue("x");Last-write-wins (no layering):
mock.process.mockReturnValue("default"); // Set defaultmock.process.calledWith("a").mockReturnValue("matched"); // Add matcher
mock.process("a"); // Returns "matched" ✅mock.process("b"); // Returns undefined ❌ (should be "default")Order matters incorrectly:
// calledWith THEN default → default overwrites everythingmock.process.calledWith("a").mockReturnValue("matched");mock.process.mockReturnValue("default");mock.process("a"); // Returns "default" ❌3. Import Issues
// ❌ FAILS: "mock is not a function"import mock from "@tkoehlerlg/bun-mock-extended";
// ✅ Only named import worksimport { mock } from "@tkoehlerlg/bun-mock-extended";4. mockDeep with Implementation Loses Mock Methods
const mockDb = mockDeep<DatabaseService>({ query: async (sql) => results[sql],});mockDb.query.mockResolvedValue([]); // TypeError: not a functionThe Type Safety Argument
The main value proposition of bun-mock-extended is type safety. But consider:
- Tests fail anyway - If you rename a method, the test fails at runtime
- Error messages are clear -
undefined is not a functionpoints to the problem - IDE refactoring not used - In AI-assisted workflows, we don’t use “Rename Symbol”
- Tests run frequently - Errors are caught immediately
Type safety in mocks is mostly ceremony when you run tests after every change.
API Compatibility Summary
| Feature | Status |
|---|---|
mock<T>() | ⚠️ Works, but why bother |
mockDeep<T>() | ❌ Broken with NestJS |
calledWith() | ❌ Multiple issues |
expect.any() matchers | ❌ Not supported |
| Default import | ❌ Broken |
| Named import | ✅ Works |
Recommendation
Use raw bun:test mocks. See Raw Mocks Guide for the recommended pattern.
The simplicity of raw mocks outweighs the theoretical benefit of type safety that bun-mock-extended provides.