Spying on Functions in Vitest
In Vitest, spies allow you to monitor and intercept function calls without modifying the original implementation. They are useful for:
- Tracking the number of times a function is called.
- Verifying arguments passed to a function.
- Checking return values of a function.
- Restoring the original function after testing.
Vitest provides the vi.spyOn method to create spies on object methods, making it easier to test interactions within your code.
Using Spies in Vitest
1. Basic Spy Example
import { describe, it, expect, vi } from 'vitest';
const math = {
add: (a, b) => a + b,
};
describe('Spy Example', () => {
it('tracks calls to the add method', () => {
const spy = vi.spyOn(math, 'add');
math.add(1, 2);
math.add(3, 4);
expect(spy).toHaveBeenCalled();
expect(spy).toHaveBeenCalledTimes(2);
expect(spy).toHaveBeenCalledWith(1, 2);
expect(spy).toHaveBeenCalledWith(3, 4);
spy.mockRestore();
});
});
2. Spying on Class Methods
class Calculator {
multiply(a, b) {
return a * b;
}
}
describe('Class Method Spy', () => {
it('tracks calls to the multiply method', () => {
const calculator = new Calculator();
const spy = vi.spyOn(calculator, 'multiply');
calculator.multiply(2, 3);
expect(spy).toHaveBeenCalledWith(2, 3);
expect(spy).toHaveReturnedWith(6);
spy.mockRestore();
});
});
3. Mocking Implementation with Spy
describe('Mock Implementation', () => {
it('provides a mock implementation', () => {
const obj = {
greet: (name) => `Hello, ${name}!`,
};
const spy = vi.spyOn(obj, 'greet').mockImplementation((name) => `Hi, ${name}!`);
expect(obj.greet('Alice')).toBe('Hi, Alice!');
spy.mockRestore();
});
});
4. Spying on Module Functions
// utils.js
export function sum(a, b) {
return a + b;
}
// utils.test.js
import { sum } from './utils';
import { vi } from 'vitest';
describe('Module Function Spy', () => {
it('tracks calls to the sum function', () => {
const spy = vi.spyOn({ sum }, 'sum');
sum(1, 2);
expect(spy).toHaveBeenCalledWith(1, 2);
spy.mockRestore();
});
});