Basic Function Mocks
Create mocks with themock function.
Jest Compatibility
Alternatively, you can use thejest.fn() function, as in Jest. It behaves identically.
Mock Function Properties
The result ofmock() is a new function that’s been decorated with some additional properties.
Available Properties and Methods
The following properties and methods are implemented on mock functions:| 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 this contexts for each invocation |
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()
It’s possible to track calls to a function without replacing it with a mock. UsespyOn() to create a spy; these spies can be passed to .toHaveBeenCalled() and .toHaveBeenCalledTimes().
Advanced Spy Usage
Module Mocks with mock.module()
Module mocking lets you override the behavior of a module. Usemock.module(path: string, callback: () => Object) to mock a module.
import and require.
Overriding Already Imported Modules
If you need to override a module that’s already been imported, there’s nothing special you need to do. Just callmock.module() and the module will be overridden.
Hoisting & Preloading
If you need to ensure a module is mocked before it’s imported, you should use--preload to load your mocks before your tests run.
terminal
bunfig.toml:
bunfig.toml
Module Mock Best Practices
When to Use Preload
What happens if I mock a module that’s already been imported? If you mock a module that’s already been imported, the module will be updated in the module cache. This means that any modules that import the module will get the mocked version, BUT the original module will still have been evaluated. That means that any side effects from the original module will still have happened. If you want to prevent the original module from being evaluated, you should use--preload to load your mocks before your tests run.
Practical Module Mock Examples
Mocking External Dependencies
Global Mock Functions
Clear All Mocks
Reset all mock function state (calls, results, etc.) without restoring their original implementation:.mock.calls, .mock.instances, .mock.contexts, and .mock.results properties of all mocks, but unlike mock.restore(), it does not restore the original implementation.
Restore All Mocks
Instead of manually restoring each mock individually withmockFn.mockRestore(), restore all mocks with one command by calling mock.restore(). Doing so does not reset the value of modules overridden with mock.module().
mock.restore() can reduce the amount of code in your tests by adding it to afterEach blocks in each test file or even in your test preload code.
Vitest Compatibility
For added compatibility with tests written for Vitest, Bun provides thevi global object as an alias for parts of the Jest mocking API:
Implementation Details
Understanding howmock.module() works helps you use it more effectively:
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 actually imported or required.Path Resolution
Bun automatically resolves the module specifier as though you were doing an import, 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 is recommended for mocks that need to prevent side effects.
Live Bindings
Mocked ESM modules maintain live bindings, so changing the mock will update 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
__mocks__ directory and auto-mocking are not supported yet. If this is blocking you from switching to Bun, please file an issue.