Mockowanie to tworzenie sztucznych wersji funkcji, modułów lub obiektów. W Parku Jurajskim to jak tworzenie modeli dinozaurów do testów bezpieczeństwa zamiast używania prawdziwych bestii.
jest.fn() tworzy "pustą" funkcję, która rejestruje wszystkie wywołania.1test('jest.fn() - podstawy', () => {
2 // Tworzenie mock funkcji
3 const feedDino = jest.fn();
4
5 // Wywołanie mock funkcji
6 feedDino('Rex', 'meat');
7 feedDino('Brachio', 'plants');
8
9 // Sprawdzanie wywołań
10 expect(feedDino).toHaveBeenCalled();
11 expect(feedDino).toHaveBeenCalledTimes(2);
12 expect(feedDino).toHaveBeenCalledWith('Rex', 'meat');
13 expect(feedDino).toHaveBeenLastCalledWith('Brachio', 'plants');
14});Możesz nadać mockowi zachowanie:
1test('mock z implementacją', () => {
2 // Mock z wartością zwracaną
3 const getHealth = jest.fn().mockReturnValue(100);
4 expect(getHealth()).toBe(100);
5
6 // Mock z różnymi wartościami dla kolejnych wywołań
7 const checkSensor = jest.fn()
8 .mockReturnValueOnce('OK')
9 .mockReturnValueOnce('WARNING')
10 .mockReturnValueOnce('DANGER');
11
12 expect(checkSensor()).toBe('OK');
13 expect(checkSensor()).toBe('WARNING');
14 expect(checkSensor()).toBe('DANGER');
15
16 // Mock z własną implementacją
17 const calculateDamage = jest.fn((attack, defense) => {
18 return Math.max(0, attack - defense);
19 });
20
21 expect(calculateDamage(50, 30)).toBe(20);
22 expect(calculateDamage(10, 30)).toBe(0);
23});jest.mock() pozwala zastąpić cały moduł mockiem:1// Plik: alertService.js
2export function sendAlert(zone, message) {
3 // W rzeczywistości wysyła email/SMS - nie chcemy tego w testach!
4 return fetch('/api/alerts', {
5 method: 'POST',
6 body: JSON.stringify({ zone, message })
7 });
8}
9
10// Plik: securitySystem.test.js
11jest.mock('./alertService');
12
13const { sendAlert } = require('./alertService');
14
15describe('SecuritySystem', () => {
16 beforeEach(() => {
17 // Resetuj mocki przed każdym testem
18 sendAlert.mockClear();
19 sendAlert.mockResolvedValue({ status: 'sent' });
20 });
21
22 it('should send alert on breach', async () => {
23 const system = new SecuritySystem();
24 await system.reportBreach('Zone A');
25
26 expect(sendAlert).toHaveBeenCalledWith(
27 'Zone A',
28 expect.stringContaining('naruszenie')
29 );
30 });
31});spyOn monitoruje istniejącą metodę bez jej zastępowania (domyślnie).1test('spyOn - monitorowanie metody', () => {
2 const park = {
3 dinosaurs: [],
4 addDinosaur(dino) {
5 this.dinosaurs.push(dino);
6 return this.dinosaurs.length;
7 },
8 getDinosaurCount() {
9 return this.dinosaurs.length;
10 }
11 };
12
13 // Szpieguj metodę - zachowuje oryginalną implementację
14 const spy = jest.spyOn(park, 'addDinosaur');
15
16 park.addDinosaur({ name: 'Rex' });
17 park.addDinosaur({ name: 'Blue' });
18
19 // Sprawdź wywołania
20 expect(spy).toHaveBeenCalledTimes(2);
21 expect(spy).toHaveBeenCalledWith({ name: 'Rex' });
22
23 // Oryginalna funkcja nadal działa!
24 expect(park.dinosaurs).toHaveLength(2);
25
26 // Przywróć oryginalną implementację
27 spy.mockRestore();
28});1test('spyOn - podmiana implementacji', () => {
2 const api = {
3 fetchDinoData(id) {
4 // Normalne wywołanie API - nie chcemy tego w testach
5 return fetch(`/api/dinosaurs/${id}`);
6 }
7 };
8
9 // Zastąp implementację na czas testu
10 const spy = jest.spyOn(api, 'fetchDinoData').mockImplementation((id) => {
11 return Promise.resolve({
12 id,
13 name: 'Mock Rex',
14 species: 'T-Rex'
15 });
16 });
17
18 // Teraz fetchDinoData zwraca mock data
19 api.fetchDinoData('001').then(data => {
20 expect(data.name).toBe('Mock Rex');
21 });
22
23 spy.mockRestore();
24});Jest udostępnia bogaty zestaw matcherów dla mocków:
1test('matchery dla mocków', () => {
2 const callback = jest.fn();
3
4 callback('Rex');
5 callback('Blue', 'raptor');
6
7 // Czy został wywołany?
8 expect(callback).toHaveBeenCalled();
9
10 // Ile razy?
11 expect(callback).toHaveBeenCalledTimes(2);
12
13 // Z jakimi argumentami?
14 expect(callback).toHaveBeenCalledWith('Rex');
15 expect(callback).toHaveBeenNthCalledWith(1, 'Rex');
16 expect(callback).toHaveBeenNthCalledWith(2, 'Blue', 'raptor');
17
18 // Dostęp do szczegółów wywołań
19 expect(callback.mock.calls).toHaveLength(2);
20 expect(callback.mock.calls[0]).toEqual(['Rex']);
21 expect(callback.mock.calls[1]).toEqual(['Blue', 'raptor']);
22});