Jest Mock Implementation Change Fix
In this tutorial, you'll learn about Jest Mock Implementation Change Fix. We cover key concepts, practical examples, and best practices.
Your mock function keeps returning the same value even after you called mockImplementation() — or the implementation you set gets ignored entirely.
The Problem
// WRONG — implementation set after the mock is used
const mockFn = jest.fn();
mockFn();
mockFn.mockImplementation(() => 'new value');
mockFn();
expect(mockFn).toHaveNthReturnedWith(2, 'new value'); // Might FAIL
Expected: "new value"
Received: undefined
The first call to mockFn() returned undefined because no implementation was set yet. Calling mockImplementation() after the function is already invoked only affects future calls.
Step-by-Step Fix
1. Set implementation before use
// RIGHT — set implementation first
const mockFn = jest.fn().mockImplementation(() => 'value');
expect(mockFn()).toBe('value');
expect(mockFn()).toBe('value');
2. Use mockImplementationOnce for one-time behavior
// RIGHT — one-time implementation
const mockFn = jest.fn()
.mockImplementationOnce(() => 'first call')
.mockImplementationOnce(() => 'second call')
.mockImplementation(() => 'default');
expect(mockFn()).toBe('first call');
expect(mockFn()).toBe('second call');
expect(mockFn()).toBe('default');
expect(mockFn()).toBe('default');
3. Chain implementations conditionally
// RIGHT — dynamic mock behavior
const mockDb = jest.fn();
mockDb.mockImplementation((query) => {
if (query.includes('SELECT')) return [{ id: 1 }];
if (query.includes('DELETE')) return { affectedRows: 3 };
throw new Error('Unsupported query');
});
expect(mockDb('SELECT * FROM users')).toEqual([{ id: 1 }]);
expect(mockDb('DELETE FROM users')).toEqual({ affectedRows: 3 });
4. Reset and replace implementations
// RIGHT — reset before redefining
const mockFn = jest.fn().mockReturnValue('first');
mockFn.mockReset();
mockFn.mockImplementation(() => 'second');
expect(mockFn()).toBe('second');
Expected output:
PASS tests/mockImplementation.test.js
✓ handles one-time implementations (5 ms)
✓ uses dynamic behavior (6 ms)
✓ resets correctly (3 ms)
Prevention Tips
- Set
mockImplementation()before calling the mocked function - Use
mockImplementationOnce()for varying return values - Call
mockReset()before redefining implementations - Prefer
mockReturnValue()for simple return values - Chain multiple
mockImplementationOncecalls before a default
Common Mistakes with mock implementation
- Non-exhaustive pattern matches that compile with warnings then crash at runtime
- Misunderstanding that
Stringis[Char]with poor performance for large text operations - Using
foldlinstead offoldl'causing stack overflow on large lists
These mistakes appear frequently in real-world JEST code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.
Practice Exercise
Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.
This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.
FAQ
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro