Jest Mock Promise Not Resolving Fix
In this tutorial, you'll learn about Jest Mock Promise Not Resolving Fix. We cover key concepts, practical examples, and best practices.
Your mock promise stays pending — the test times out or the .then() callback never fires. The mocked async function doesn't resolve or reject as expected.
The Problem
// WRONG — returning a plain value from an async mock
jest.mock('./api');
import { fetchData } from './api';
fetchData.mockImplementation(() => { data: 'test' });
// Returns undefined, not a promise!
test('gets data', async () => {
const result = await fetchData();
expect(result).toBeUndefined(); // Not what we wanted
});
Received: undefined
Returning a plain object from an async function doesn't work — the function needs to return a promise that resolves to the expected value.
Step-by-Step Fix
1. Use mockResolvedValue for resolving promises
// RIGHT — mock returns a resolved promise
jest.mock('./api');
import { fetchData } from './api';
fetchData.mockResolvedValue({ id: 1, name: 'Alice' });
test('fetches user data', async () => {
const data = await fetchData(1);
expect(data.name).toBe('Alice');
});
2. Use mockRejectedValue for error scenarios
// RIGHT — mock returns a rejected promise
fetchData.mockRejectedValue(new Error('Network Error'));
test('handles fetch failure', async () => {
await expect(fetchData(1)).rejects.toThrow('Network Error');
});
3. Chain resolve and reject sequences
// RIGHT — first call succeeds, second fails
fetchData
.mockResolvedValueOnce({ id: 1 })
.mockRejectedValueOnce(new Error('Not found'));
await expect(fetchData(1)).resolves.toEqual({ id: 1 });
await expect(fetchData(2)).rejects.toThrow('Not found');
4. Delayed promise resolution
// RIGHT — custom async behavior
fetchData.mockImplementation((id) => {
return new Promise((resolve) => {
setTimeout(() => resolve({ id }), 100);
});
});
const result = await fetchData(42);
expect(result.id).toBe(42);
Expected output:
PASS tests/promise.test.js
✓ fetches user data (12 ms)
✓ handles fetch failure (4 ms)
✓ chains resolve and reject (6 ms)
Prevention Tips
- Use
mockResolvedValue()for successful async scenarios - Use
mockRejectedValue()for error handling tests - Use
mockResolvedValueOnce()for sequential async behavior - Avoid returning plain values from async mocks
- Always await async assertions in tests
Common Mistakes with mock promise
- Using
returnto exit a function early instead of wrapping a pure value in the monad - Mixing let bindings with <- bindings in do notation, producing type errors
- Overlapping type class instances that cause GHC to reject the program with ambiguous dispatch errors
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