Funzioni Mock
Questa pagina è stata tradotta da PageTurner AI (beta). Non ufficialmente approvata dal progetto. Hai trovato un errore? Segnala problema →
Le funzioni mock sono anche conosciute come "spie" perché permettono di osservare il comportamento di una funzione chiamata indirettamente da altro codice, andando oltre il semplice test dell'output. Puoi creare una funzione mock con jest.fn(). Se non viene fornita un'implementazione, la funzione mock restituirà undefined quando invocata.
Questa pagina è stata tradotta da PageTurner AI (beta). Non ufficialmente approvata dal progetto. Hai trovato un errore? Segnala problema →
Gli esempi TypeScript in questa pagina funzioneranno come documentato solo se importi esplicitamente le API di Jest:
import {expect, jest, test} from '@jest/globals';
Consulta la guida Per iniziare per i dettagli su come configurare Jest con TypeScript.
Metodi
- Riferimento
mockFn.getMockImplementation()mockFn.getMockName()mockFn.mock.callsmockFn.mock.resultsmockFn.mock.instancesmockFn.mock.contextsmockFn.mock.lastCallmockFn.mockClear()mockFn.mockReset()mockFn.mockRestore()mockFn.mockImplementation(fn)mockFn.mockImplementationOnce(fn)mockFn.mockName(name)mockFn.mockReturnThis()mockFn.mockReturnValue(value)mockFn.mockReturnValueOnce(value)mockFn.mockResolvedValue(value)mockFn.mockResolvedValueOnce(value)mockFn.mockRejectedValue(value)mockFn.mockRejectedValueOnce(value)mockFn.withImplementation(fn, callback)
- Proprietà sostituite
- Utilizzo con TypeScript
Riferimento
mockFn.getMockImplementation()
Restituisce l'implementazione corrente della funzione mock impostata da mockImplementation(). Restituisce undefined se nessuna implementazione è stata impostata.
- JavaScript
- TypeScript
const mockFn = jest.fn();
mockFn.getMockImplementation(); // undefined
mockFn.mockImplementation(() => 42);
mockFn.getMockImplementation(); // () => 42
import {jest} from '@jest/globals';
const mockFn = jest.fn<() => number>();
mockFn.getMockImplementation(); // undefined
mockFn.mockImplementation(() => 42);
mockFn.getMockImplementation(); // () => 42
mockFn.getMockName()
Restituisce il nome stringa della funzione mock impostato chiamando .mockName().
mockFn.mock.calls
Un array contenente gli argomenti di tutte le chiamate effettuate a questa funzione mock. Ogni elemento dell'array è un array di argomenti passati durante la chiamata.
Esempio: una funzione mock f chiamata due volte con gli argomenti f('arg1', 'arg2') e poi f('arg3', 'arg4') avrà un array mock.calls simile a:
[
['arg1', 'arg2'],
['arg3', 'arg4'],
];
mockFn.mock.results
Un array contenente i risultati di tutte le chiamate effettuate a questa funzione mock. Ogni elemento è un oggetto con una proprietà type e una proprietà value. type può essere uno dei seguenti:
-
'return'- Indica che la chiamata è completata con un ritorno normale. -
'throw'- Indica che la chiamata è completata lanciando un valore. -
'incomplete'- Indica che la chiamata non è ancora completata. Si verifica quando si testa il risultato all'interno della funzione mock stessa o in una funzione da essa chiamata.
La proprietà value contiene il valore ritornato o lanciato. value è undefined quando type === 'incomplete'.
Esempio: una funzione mock f chiamata tre volte, che restituisce 'result1', lancia un errore e poi restituisce 'result2', avrà un array mock.results simile a:
[
{
type: 'return',
value: 'result1',
},
{
type: 'throw',
value: {
/* Error instance */
},
},
{
type: 'return',
value: 'result2',
},
];
mockFn.mock.instances
Un array contenente tutte le istanze di oggetti create da questa funzione mock usando new.
Esempio: una funzione mock istanziata due volte avrà il seguente array mock.instances:
const mockFn = jest.fn();
const a = new mockFn();
const b = new mockFn();
mockFn.mock.instances[0] === a; // true
mockFn.mock.instances[1] === b; // true
mockFn.mock.contexts
Un array contenente i contesti di tutte le chiamate della funzione mock.
Un contesto è il valore this che una funzione riceve quando chiamata. Il contesto può essere impostato con Function.prototype.bind, Function.prototype.call o Function.prototype.apply.
Per esempio:
const mockFn = jest.fn();
const boundMockFn = mockFn.bind(thisContext0);
boundMockFn('a', 'b');
mockFn.call(thisContext1, 'a', 'b');
mockFn.apply(thisContext2, ['a', 'b']);
mockFn.mock.contexts[0] === thisContext0; // true
mockFn.mock.contexts[1] === thisContext1; // true
mockFn.mock.contexts[2] === thisContext2; // true
mockFn.mock.lastCall
Un array contenente gli argomenti dell'ultima chiamata effettuata a questa funzione mock. Se la funzione non è stata chiamata, restituisce undefined.
Esempio: una funzione mock f chiamata due volte con gli argomenti f('arg1', 'arg2') e poi f('arg3', 'arg4') avrà un array mock.lastCall simile a:
['arg3', 'arg4'];
mockFn.mockClear()
Cancella tutte le informazioni memorizzate negli array mockFn.mock.calls, mockFn.mock.instances, mockFn.mock.contexts e mockFn.mock.results. Utile per ripulire i dati d'uso tra due asserzioni.
L'opzione di configurazione clearMocks è disponibile per cancellare automaticamente i mock prima di ogni test.
Attenzione: mockFn.mockClear() sostituirà completamente mockFn.mock, non solo resetterà i valori delle sue proprietà! Dovresti quindi evitare di assegnare mockFn.mock ad altre variabili, temporanee o meno, per non rischiare di accedere a dati obsoleti.
mockFn.mockReset()
Esegue tutto ciò che fa mockFn.mockClear(), e inoltre sostituisce l'implementazione mock con una funzione vuota che restituisce undefined.
L'opzione di configurazione resetMocks è disponibile per resettare automaticamente i mock prima di ogni test.
mockFn.mockRestore()
Esegue tutto ciò che fa mockFn.mockReset(), e inoltre ripristina l'implementazione originale (non mockata).
È utile quando vuoi usare funzioni mock in alcuni test e ripristinare l'implementazione originale in altri.
L'opzione di configurazione restoreMocks è disponibile per ripristinare automaticamente i mock prima di ogni test.
mockFn.mockRestore() funziona solo quando il mock è stato creato con jest.spyOn(). Dovrai quindi gestire manualmente il ripristino quando assegni direttamente jest.fn().
mockFn.mockImplementation(fn)
Accetta una funzione da utilizzare come implementazione del mock. Il mock continuerà comunque a registrare tutte le chiamate ricevute e le istanze create – l'unica differenza è che l'implementazione verrà eseguita quando il mock è chiamato.
jest.fn(implementation) è una forma abbreviata per jest.fn().mockImplementation(implementation).
- JavaScript
- TypeScript
const mockFn = jest.fn(scalar => 42 + scalar);
mockFn(0); // 42
mockFn(1); // 43
mockFn.mockImplementation(scalar => 36 + scalar);
mockFn(2); // 38
mockFn(3); // 39
import {jest} from '@jest/globals';
const mockFn = jest.fn((scalar: number) => 42 + scalar);
mockFn(0); // 42
mockFn(1); // 43
mockFn.mockImplementation(scalar => 36 + scalar);
mockFn(2); // 38
mockFn(3); // 39
.mockImplementation() può essere usato anche per mockare i costruttori di classi:
- JavaScript
- TypeScript
module.exports = class SomeClass {
method(a, b) {}
};
const SomeClass = require('./SomeClass');
jest.mock('./SomeClass'); // this happens automatically with automocking
const mockMethod = jest.fn();
SomeClass.mockImplementation(() => {
return {
method: mockMethod,
};
});
const some = new SomeClass();
some.method('a', 'b');
console.log('Calls to method:', mockMethod.mock.calls);
export class SomeClass {
method(a: string, b: string): void {}
}
import {jest} from '@jest/globals';
import {SomeClass} from './SomeClass';
jest.mock('./SomeClass'); // this happens automatically with automocking
const mockMethod = jest.fn<(a: string, b: string) => void>();
jest.mocked(SomeClass).mockImplementation(() => {
return {
method: mockMethod,
};
});
const some = new SomeClass();
some.method('a', 'b');
console.log('Calls to method:', mockMethod.mock.calls);
mockFn.mockImplementationOnce(fn)
Accetta una funzione che verrà utilizzata come implementazione del mock per una singola chiamata alla funzione mockata. Può essere concatenata per produrre risultati diversi in chiamate successive.
- JavaScript
- TypeScript
const mockFn = jest
.fn()
.mockImplementationOnce(cb => cb(null, true))
.mockImplementationOnce(cb => cb(null, false));
mockFn((err, val) => console.log(val)); // true
mockFn((err, val) => console.log(val)); // false
import {jest} from '@jest/globals';
const mockFn = jest
.fn<(cb: (a: null, b: boolean) => void) => void>()
.mockImplementationOnce(cb => cb(null, true))
.mockImplementationOnce(cb => cb(null, false));
mockFn((err, val) => console.log(val)); // true
mockFn((err, val) => console.log(val)); // false
Quando la funzione mockata esaurisce le implementazioni definite con .mockImplementationOnce(), eseguirà l'implementazione predefinita impostata con jest.fn(() => defaultValue) o .mockImplementation(() => defaultValue) se sono state chiamate:
const mockFn = jest
.fn(() => 'default')
.mockImplementationOnce(() => 'first call')
.mockImplementationOnce(() => 'second call');
mockFn(); // 'first call'
mockFn(); // 'second call'
mockFn(); // 'default'
mockFn(); // 'default'
mockFn.mockName(name)
Accetta una stringa da utilizzare negli output dei test al posto di 'jest.fn()' per indicare quale funzione mock è referenziata.
Per esempio:
const mockFn = jest.fn().mockName('mockedFunction');
// mockFn();
expect(mockFn).toHaveBeenCalled();
Risulterà in questo errore:
expect(mockedFunction).toHaveBeenCalled()
Expected number of calls: >= 1
Received number of calls: 0
mockFn.mockReturnThis()
Forma abbreviata per:
jest.fn(function () {
return this;
});
mockFn.mockReturnValue(value)
Forma abbreviata per:
jest.fn().mockImplementation(() => value);
Accetta un valore che verrà restituito ogni volta che la funzione mockata è chiamata.
- JavaScript
- TypeScript
const mock = jest.fn();
mock.mockReturnValue(42);
mock(); // 42
mock.mockReturnValue(43);
mock(); // 43
import {jest} from '@jest/globals';
const mock = jest.fn<() => number>();
mock.mockReturnValue(42);
mock(); // 42
mock.mockReturnValue(43);
mock(); // 43
mockFn.mockReturnValueOnce(value)
Forma abbreviata per:
jest.fn().mockImplementationOnce(() => value);
Accetta un valore che verrà restituito per una singola chiamata alla funzione mockata. Può essere concatenato per far sì che chiamate successive restituiscano valori diversi. Quando non ci sono più valori mockReturnValueOnce da utilizzare, le chiamate restituiranno il valore specificato da mockReturnValue.
- JavaScript
- TypeScript
const mockFn = jest
.fn()
.mockReturnValue('default')
.mockReturnValueOnce('first call')
.mockReturnValueOnce('second call');
mockFn(); // 'first call'
mockFn(); // 'second call'
mockFn(); // 'default'
mockFn(); // 'default'
import {jest} from '@jest/globals';
const mockFn = jest
.fn<() => string>()
.mockReturnValue('default')
.mockReturnValueOnce('first call')
.mockReturnValueOnce('second call');
mockFn(); // 'first call'
mockFn(); // 'second call'
mockFn(); // 'default'
mockFn(); // 'default'
mockFn.mockResolvedValue(value)
Forma abbreviata per:
jest.fn().mockImplementation(() => Promise.resolve(value));
Utile per mockare funzioni asincrone in test asincroni:
- JavaScript
- TypeScript
test('async test', async () => {
const asyncMock = jest.fn().mockResolvedValue(43);
await asyncMock(); // 43
});
import {jest, test} from '@jest/globals';
test('async test', async () => {
const asyncMock = jest.fn<() => Promise<number>>().mockResolvedValue(43);
await asyncMock(); // 43
});
mockFn.mockResolvedValueOnce(value)
Forma abbreviata per:
jest.fn().mockImplementationOnce(() => Promise.resolve(value));
Utile per risolvere valori diversi in chiamate asincrone multiple:
- JavaScript
- TypeScript
test('async test', async () => {
const asyncMock = jest
.fn()
.mockResolvedValue('default')
.mockResolvedValueOnce('first call')
.mockResolvedValueOnce('second call');
await asyncMock(); // 'first call'
await asyncMock(); // 'second call'
await asyncMock(); // 'default'
await asyncMock(); // 'default'
});
import {jest, test} from '@jest/globals';
test('async test', async () => {
const asyncMock = jest
.fn<() => Promise<string>>()
.mockResolvedValue('default')
.mockResolvedValueOnce('first call')
.mockResolvedValueOnce('second call');
await asyncMock(); // 'first call'
await asyncMock(); // 'second call'
await asyncMock(); // 'default'
await asyncMock(); // 'default'
});
mockFn.mockRejectedValue(value)
Forma abbreviata per:
jest.fn().mockImplementation(() => Promise.reject(value));
Utile per creare funzioni mock asincrone che verranno sempre respinte:
- JavaScript
- TypeScript
test('async test', async () => {
const asyncMock = jest
.fn()
.mockRejectedValue(new Error('Async error message'));
await asyncMock(); // throws 'Async error message'
});
import {jest, test} from '@jest/globals';
test('async test', async () => {
const asyncMock = jest
.fn<() => Promise<never>>()
.mockRejectedValue(new Error('Async error message'));
await asyncMock(); // throws 'Async error message'
});
mockFn.mockRejectedValueOnce(value)
Forma abbreviata per:
jest.fn().mockImplementationOnce(() => Promise.reject(value));
Utile insieme a .mockResolvedValueOnce() o per respingere con eccezioni diverse in più chiamate asincrone:
- JavaScript
- TypeScript
test('async test', async () => {
const asyncMock = jest
.fn()
.mockResolvedValueOnce('first call')
.mockRejectedValueOnce(new Error('Async error message'));
await asyncMock(); // 'first call'
await asyncMock(); // throws 'Async error message'
});
import {jest, test} from '@jest/globals';
test('async test', async () => {
const asyncMock = jest
.fn<() => Promise<string>>()
.mockResolvedValueOnce('first call')
.mockRejectedValueOnce(new Error('Async error message'));
await asyncMock(); // 'first call'
await asyncMock(); // throws 'Async error message'
});
mockFn.withImplementation(fn, callback)
Accetta una funzione da utilizzare temporaneamente come implementazione del mock durante l'esecuzione del callback.
test('test', () => {
const mock = jest.fn(() => 'outside callback');
mock.withImplementation(
() => 'inside callback',
() => {
mock(); // 'inside callback'
},
);
mock(); // 'outside callback'
});
mockFn.withImplementation può essere utilizzato indipendentemente dal fatto che il callback sia asincrono (restituisca un thenable). Se il callback è asincrono, verrà restituita una promise. Attendere la promise attenderà il callback e reimposterà l'implementazione.
test('async test', async () => {
const mock = jest.fn(() => 'outside callback');
// We await this call since the callback is async
await mock.withImplementation(
() => 'inside callback',
async () => {
mock(); // 'inside callback'
},
);
mock(); // 'outside callback'
});
Proprietà sostituite
replacedProperty.replaceValue(value)
Modifica il valore di una proprietà già sostituita. Utile quando si desidera sostituire una proprietà e poi modificare il valore in test specifici. In alternativa, è possibile chiamare jest.replaceProperty() più volte sulla stessa proprietà.
replacedProperty.restore()
Ripristina la proprietà dell'oggetto al valore originale.
Attenzione: replacedProperty.restore() funziona solo quando il valore della proprietà è stato sostituito con jest.replaceProperty().
L'opzione di configurazione restoreMocks è disponibile per ripristinare automaticamente le proprietà sostituite prima di ogni test.
Utilizzo con TypeScript
Questa pagina è stata tradotta da PageTurner AI (beta). Non ufficialmente approvata dal progetto. Hai trovato un errore? Segnala problema →
Gli esempi TypeScript in questa pagina funzioneranno come documentato solo se importi esplicitamente le API di Jest:
import {expect, jest, test} from '@jest/globals';
Consulta la guida Per iniziare per i dettagli su come configurare Jest con TypeScript.
jest.fn(implementation?)
I tipi corretti per il mock verranno dedotti se viene passata un'implementazione a jest.fn(). In molti casi d'uso l'implementazione viene omessa. Per garantire la sicurezza dei tipi, è possibile passare un argomento di tipo generico (vedere anche gli esempi precedenti per ulteriori riferimenti):
import {expect, jest, test} from '@jest/globals';
import type add from './add';
import calculate from './calc';
test('calculate calls add', () => {
// Create a new mock that can be used in place of `add`.
const mockAdd = jest.fn<typeof add>();
// `.mockImplementation()` now can infer that `a` and `b` are `number`
// and that the returned value is a `number`.
mockAdd.mockImplementation((a, b) => {
// Yes, this mock is still adding two numbers but imagine this
// was a complex function we are mocking.
return a + b;
});
// `mockAdd` is properly typed and therefore accepted by anything
// requiring `add`.
calculate(mockAdd, 1, 2);
expect(mockAdd).toHaveBeenCalledTimes(1);
expect(mockAdd).toHaveBeenCalledWith(1, 2);
});
jest.Mock<T>
Costruisce il tipo di una funzione mock, ad esempio il tipo restituito da jest.fn(). Può essere utile se è necessario definire una funzione mock ricorsiva:
import {jest} from '@jest/globals';
const sumRecursively: jest.Mock<(value: number) => number> = jest.fn(value => {
if (value === 0) {
return 0;
} else {
return value + fn(value - 1);
}
});
jest.Mocked<Source>
L'utility type jest.Mocked<Source> restituisce il tipo Source avvolto nelle definizioni dei tipi della funzione mock di Jest.
import {expect, jest, test} from '@jest/globals';
import type {fetch} from 'node-fetch';
jest.mock('node-fetch');
let mockedFetch: jest.Mocked<typeof fetch>;
afterEach(() => {
mockedFetch.mockClear();
});
test('makes correct call', () => {
mockedFetch = getMockedFetch();
// ...
});
test('returns correct data', () => {
mockedFetch = getMockedFetch();
// ...
});
Possono essere passati come argomento di tipo a jest.Mocked<Source> tipi di classi, funzioni o oggetti. Per vincolare il tipo di input, utilizzare: jest.MockedClass<Source>, jest.MockedFunction<Source> o jest.MockedObject<Source>.
jest.Replaced<Source>
L'utility type jest.Replaced<Source> restituisce il tipo Source avvolto nelle definizioni dei tipi delle proprietà sostituite di Jest.
export function isLocalhost(): boolean {
return process.env['HOSTNAME'] === 'localhost';
}
import {afterEach, expect, it, jest} from '@jest/globals';
import {isLocalhost} from '../utils';
let replacedEnv: jest.Replaced<typeof process.env> | undefined = undefined;
afterEach(() => {
replacedEnv?.restore();
});
it('isLocalhost should detect localhost environment', () => {
replacedEnv = jest.replaceProperty(process, 'env', {HOSTNAME: 'localhost'});
expect(isLocalhost()).toBe(true);
});
it('isLocalhost should detect non-localhost environment', () => {
replacedEnv = jest.replaceProperty(process, 'env', {HOSTNAME: 'example.com'});
expect(isLocalhost()).toBe(false);
});
jest.mocked(source, options?)
Il metodo helper mocked() avvolge i tipi dell'oggetto source e dei suoi membri annidati profondamente con le definizioni dei tipi della funzione mock di Jest. È possibile passare {shallow: true} come argomento options per disabilitare il comportamento di mock profondo.
Restituisce l'oggetto source.
export const song = {
one: {
more: {
time: (t: number) => {
return t;
},
},
},
};
import {expect, jest, test} from '@jest/globals';
import {song} from './song';
jest.mock('./song');
jest.spyOn(console, 'log');
const mockedSong = jest.mocked(song);
// or through `jest.Mocked<Source>`
// const mockedSong = song as jest.Mocked<typeof song>;
test('deep method is typed correctly', () => {
mockedSong.one.more.time.mockReturnValue(12);
expect(mockedSong.one.more.time(10)).toBe(12);
expect(mockedSong.one.more.time.mock.calls).toHaveLength(1);
});
test('direct usage', () => {
jest.mocked(console.log).mockImplementation(() => {
return;
});
console.log('one more time');
expect(jest.mocked(console.log).mock.calls).toHaveLength(1);
});
jest.Spied<Source>
Costruisce il tipo di una classe o funzione spiate (ovvero il tipo restituito da jest.spyOn()).
import {jest} from '@jest/globals';
export function setDateNow(now: number): jest.Spied<typeof Date.now> {
return jest.spyOn(Date, 'now').mockReturnValue(now);
}
import {afterEach, expect, type jest, test} from '@jest/globals';
import {setDateNow} from './__utils__/setDateNow';
let spiedDateNow: jest.Spied<typeof Date.now> | undefined = undefined;
afterEach(() => {
spiedDateNow?.mockReset();
});
test('renders correctly with a given date', () => {
spiedDateNow = setDateNow(1_482_363_367_071);
// ...
expect(spiedDateNow).toHaveBeenCalledTimes(1);
});
Possono essere passati come argomento di tipo a jest.Spied<Source> tipi di classi o funzioni. Per vincolare il tipo di input, utilizzare: jest.SpiedClass<Source> o jest.SpiedFunction<Source>.
Utilizzare jest.SpiedGetter<Source> o jest.SpiedSetter<Source> per creare rispettivamente il tipo di un getter o setter spiate.