Basic Function Mocks
Create mocks with themock function.
Jest Compatibility
You can also usejest.fn(), as in Jest. It behaves identically.
Mock Function Properties
mock() returns a new function decorated with additional properties.
Available Properties and Methods
Mock functions implement the following properties and methods:| Property/Method | Description |
|---|---|
mockFn.getMockName() | Returns the mock name |
mockFn.mock.calls | Array of call arguments for each invocation |
mockFn.mock.results | Array of return values for each invocation |
mockFn.mock.instances | Array of instances created with new |
mockFn.mock.contexts | Array of this contexts for each invocation |
mockFn.mock.lastCall | Arguments of the most recent call |
mockFn.mockClear() | Clears call history |
mockFn.mockReset() | Clears call history and removes implementation |
mockFn.mockRestore() | Restores original implementation |
mockFn.mockImplementation(fn) | Sets a new implementation |
mockFn.mockImplementationOnce(fn) | Sets implementation for next call only |
mockFn.mockName(name) | Sets the mock name |
mockFn.mockReturnThis() | Sets the return value to this |
mockFn.mockReturnValue(value) | Sets a return value |
mockFn.mockReturnValueOnce(value) | Sets return value for next call only |
mockFn.mockResolvedValue(value) | Sets a resolved Promise value |
mockFn.mockResolvedValueOnce(value) | Sets resolved Promise for next call only |
mockFn.mockRejectedValue(value) | Sets a rejected Promise value |
mockFn.mockRejectedValueOnce(value) | Sets rejected Promise for next call only |
mockFn.withImplementation(fn, callback) | Temporarily changes implementation |
Practical Examples
Basic Mock Usage
Dynamic Mock Implementations
Async Mocks
Spies with spyOn()
UsespyOn() to track calls to a function without replacing it with a mock. Spies can be passed to .toHaveBeenCalled() and .toHaveBeenCalledTimes().
Advanced Spy Usage
Module Mocks with mock.module()
Usemock.module(path: string, callback: () => Object) to override the behavior of a module.
import and require.
Overriding Already Imported Modules
Callingmock.module() overrides the module even if it has already been imported.
Hoisting & Preloading
To make sure a module is mocked before it’s imported, use--preload to load your mocks before your tests run.
terminal
--preload every time you run tests, add it to your bunfig.toml:
bunfig.toml
Module Mock Best Practices
When to Use Preload
Mocking a module that’s already been imported updates the module cache, so anything that imports it gets the mocked version. The original module has already been evaluated, though, so its side effects have already happened. To prevent the original module from being evaluated at all, use--preload to load your mocks before your tests run.
Practical Module Mock Examples
Mocking External Dependencies
Global Mock Functions
Clear All Mocks
mock.clearAllMocks() resets the .mock.calls, .mock.instances, .mock.contexts, and .mock.results properties of every mock. Unlike mock.restore(), it does not restore the original implementation:
Reset All Mocks
jest.resetAllMocks() (and its vi.resetAllMocks() alias) calls mockFn.mockReset() on every mock: on top of what clearAllMocks() does, it drops the implementations set by mockImplementation(), mockReturnValue() and friends. It does not restore the original implementation of a spy:
Restore All Mocks
mock.restore() restores every mock at once, instead of calling mockFn.mockRestore() on each one. It does not reset modules overridden with mock.module().
mock.restore() in an afterEach block, or in your test preload script, instead of repeating cleanup in every test.
Vitest Compatibility
For added compatibility with tests written for Vitest, Bun provides thevi object as an alias for parts of the Jest mocking API:
Implementation Details
Cache Interaction
Module mocks interact with both ESM and CommonJS module caches.Lazy Evaluation
The mock factory callback is only evaluated when the module is imported or required.Path Resolution
Bun resolves the module specifier the same way it resolves animport, supporting:
- Relative paths (
'./module') - Absolute paths (
'/path/to/module') - Package names (
'lodash')
Import Timing Effects
- When mocking before first import: No side effects from the original module occur
- When mocking after import: The original module’s side effects have already happened
--preload for mocks that need to prevent side effects.
Live Bindings
Mocked ESM modules maintain live bindings, so changing the mock updates all existing imports.Advanced Patterns
Factory Functions
Conditional Mocking
Mock Cleanup Patterns
Best Practices
Keep Mocks Simple
Use Type-Safe Mocks
Test Mock Behavior
Notes
Auto-mocking
Bun does not support the__mocks__ directory or auto-mocking. If this is blocking you from switching to Bun, file an issue.