Jest SpyOn Not Working Fix
In this tutorial, you'll learn about Jest SpyOn Not Working Fix. We cover key concepts, practical examples, and best practices.
Your jest.spyOn() doesn't track calls — the spy shows 0 invocations even though the method definitely ran during the test.
The Problem
// WRONG — spying after the method is called
const calculator = {
add: (a, b) => a + b,
};
calculator.add(2, 3);
const spy = jest.spyOn(calculator, 'add');
expect(spy).toHaveBeenCalled(); // FAILS
expect(jest.fn()).toHaveBeenCalled()
Expected number of calls: 1
Received number of calls: 0
The spy was created after the method was already called. jest.spyOn() only tracks calls made after the spy is installed.
Step-by-Step Fix
1. Install the spy before calling the method
// RIGHT — spy before invocation
const calculator = {
add: (a, b) => a + b,
};
test('calls add method', () => {
const spy = jest.spyOn(calculator, 'add');
calculator.add(2, 3);
expect(spy).toHaveBeenCalledWith(2, 3);
spy.mockRestore();
});
2. Spy on class prototype methods
// RIGHT — spy on prototype
class Logger {
log(message) {
console.log(message);
}
}
test('logs message', () => {
const spy = jest.spyOn(Logger.prototype, 'log');
const logger = new Logger();
logger.log('test');
expect(spy).toHaveBeenCalledWith('test');
spy.mockRestore();
});
3. Mock the implementation while spying
// RIGHT — spy with mock implementation
const db = { query: (sql) => `Result of ${sql}` };
test('mocks database query', () => {
const spy = jest.spyOn(db, 'query').mockReturnValue('Mock result');
const result = db.query('SELECT * FROM users');
expect(result).toBe('Mock result');
expect(spy).toHaveBeenCalled();
spy.mockRestore();
});
4. Restore spies in afterEach
afterEach(() => {
jest.restoreAllMocks();
});
test('first test', () => {
const spy = jest.spyOn(console, 'log');
console.log('hello');
expect(spy).toHaveBeenCalled();
});
Expected output:
PASS tests/spy.test.js
✓ calls add method (6 ms)
✓ logs message (4 ms)
✓ mocks database query (5 ms)
Prevention Tips
- Create spies before the method is called
- Use
jest.spyOn()instead of manual mock assignments - Always call
mockRestore()or usejest.restoreAllMocks()inafterEach - Spy on
prototypefor class instance methods - Combine with
.mockImplementation()to replace behavior
Common Mistakes with mock spy
- 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
- Non-exhaustive pattern matches that compile with warnings then crash at runtime
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