Funciones Mock
Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →
Las funciones mock también se conocen como "espías" porque te permiten observar el comportamiento de una función llamada indirectamente por otro código, en lugar de solo probar su salida. Puedes crear una función mock con jest.fn(). Si no se proporciona una implementación, la función mock devolverá undefined cuando se invoque.
Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →
Los ejemplos de TypeScript en esta página solo funcionarán como se documenta si importas explícitamente las APIs de Jest:
import {expect, jest, test} from '@jest/globals';
Consulta la guía de Primeros pasos para obtener detalles sobre cómo configurar Jest con TypeScript.
Métodos
- Referencia
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)
- Propiedades Reemplazadas
- Uso con TypeScript
Referencia
mockFn.getMockName()
Devuelve el nombre asignado a la función mock mediante .mockName().
mockFn.mock.calls
Un array que contiene los argumentos de todas las llamadas realizadas a esta función mock. Cada elemento del array es un array de argumentos pasados durante la llamada.
Por ejemplo: Una función mock f llamada dos veces con los argumentos f('arg1', 'arg2') y luego f('arg3', 'arg4'), tendría un array mock.calls con este aspecto:
[
['arg1', 'arg2'],
['arg3', 'arg4'],
];
mockFn.mock.results
Un array que contiene los resultados de todas las llamadas realizadas a esta función mock. Cada entrada es un objeto con una propiedad type y una propiedad value. type puede ser uno de estos valores:
-
'return'- Indica que la llamada finalizó retornando normalmente. -
'throw'- Indica que la llamada finalizó lanzando un valor. -
'incomplete'- Indica que la llamada aún no ha finalizado. Esto ocurre si pruebas el resultado desde dentro de la propia función mock o desde una función llamada por ella.
La propiedad value contiene el valor devuelto o lanzado. value es undefined cuando type === 'incomplete'.
Por ejemplo: Una función mock f llamada tres veces que devuelve 'result1', lanza un error y luego devuelve 'result2', tendría un array mock.results con este aspecto:
[
{
type: 'return',
value: 'result1',
},
{
type: 'throw',
value: {
/* Error instance */
},
},
{
type: 'return',
value: 'result2',
},
];
mockFn.mock.instances
Un array que contiene todas las instancias de objetos creadas con esta función mock mediante new.
Por ejemplo: Una función mock instanciada dos veces tendría el siguiente 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 que contiene los contextos de todas las llamadas a la función mock.
Un contexto es el valor this que recibe una función al ser llamada. El contexto puede establecerse usando Function.prototype.bind, Function.prototype.call o Function.prototype.apply.
Por ejemplo:
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 que contiene los argumentos de la última llamada realizada a esta función mock. Devuelve undefined si la función no ha sido llamada.
Por ejemplo: Una función mock f llamada dos veces con los argumentos f('arg1', 'arg2') y luego f('arg3', 'arg4'), tendría un array mock.lastCall con este aspecto:
['arg3', 'arg4'];
mockFn.mockClear()
Limpia toda la información almacenada en los arrays mockFn.mock.calls, mockFn.mock.instances, mockFn.mock.contexts y mockFn.mock.results. Es útil para limpiar datos de uso entre dos aserciones.
La opción de configuración clearMocks permite limpiar los mocks automáticamente antes de cada prueba.
¡Cuidado! mockFn.mockClear() reemplazará todo mockFn.mock, no solo restablecerá los valores de sus propiedades. Por lo tanto, debes evitar asignar mockFn.mock a otras variables, temporales o no, para asegurarte de no acceder a datos obsoletos.
mockFn.mockReset()
Hace todo lo que hace mockFn.mockClear(), y además reemplaza la implementación simulada con una función vacía que devuelve undefined.
La opción de configuración resetMocks está disponible para restablecer mocks automáticamente antes de cada prueba.
mockFn.mockRestore()
Hace todo lo que hace mockFn.mockReset(), y además restaura la implementación original (no simulada).
Esto es útil cuando quieres simular funciones en ciertos casos de prueba y restaurar la implementación original en otros.
La opción de configuración restoreMocks está disponible para restaurar mocks automáticamente antes de cada prueba.
mockFn.mockRestore() solo funciona cuando el mock se creó con jest.spyOn(). Por lo tanto, debes encargarte de la restauración manualmente cuando asignas jest.fn() manualmente.
mockFn.mockImplementation(fn)
Acepta una función que se usará como implementación del mock. El mock en sí seguirá registrando todas las llamadas que reciba y las instancias que se generen a partir de él; la única diferencia es que la implementación también se ejecutará cuando se llame al mock.
jest.fn(implementation) es una forma abreviada de 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() también puede usarse para simular constructores de clases:
- 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)
Acepta una función que se usará como implementación del mock para una llamada a la función simulada. Se puede encadenar para que múltiples llamadas a funciones produzcan resultados diferentes.
- 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
Cuando la función simulada se quede sin implementaciones definidas con .mockImplementationOnce(), ejecutará la implementación predeterminada establecida con jest.fn(() => defaultValue) o .mockImplementation(() => defaultValue) si se llamaron:
const mockFn = jest
.fn(() => 'default')
.mockImplementationOnce(() => 'first call')
.mockImplementationOnce(() => 'second call');
mockFn(); // 'first call'
mockFn(); // 'second call'
mockFn(); // 'default'
mockFn(); // 'default'
mockFn.mockName(name)
Acepta una cadena para usar en los resultados de las pruebas en lugar de 'jest.fn()', indicando qué función simulada se está referenciando.
Por ejemplo:
const mockFn = jest.fn().mockName('mockedFunction');
// mockFn();
expect(mockFn).toHaveBeenCalled();
Resultará en este error:
expect(mockedFunction).toHaveBeenCalled()
Expected number of calls: >= 1
Received number of calls: 0
mockFn.mockReturnThis()
Forma abreviada de:
jest.fn(function () {
return this;
});
mockFn.mockReturnValue(value)
Forma abreviada de:
jest.fn().mockImplementation(() => value);
Acepta un valor que se devolverá cada vez que se llame a la función simulada.
- 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 abreviada de:
jest.fn().mockImplementationOnce(() => value);
Acepta un valor que se devolverá para una llamada a la función simulada. Se puede encadenar para que llamadas sucesivas devuelvan valores diferentes. Cuando no queden más valores mockReturnValueOnce por usar, las llamadas devolverán el valor especificado por 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 abreviada de:
jest.fn().mockImplementation(() => Promise.resolve(value));
Útil para simular funciones asíncronas en pruebas asíncronas:
- 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 abreviada de:
jest.fn().mockImplementationOnce(() => Promise.resolve(value));
Útil para resolver diferentes valores en múltiples llamadas asíncronas:
- 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 abreviada de:
jest.fn().mockImplementation(() => Promise.reject(value));
Útil para crear funciones simuladas asíncronas que siempre rechazarán:
- 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 abreviada de:
jest.fn().mockImplementationOnce(() => Promise.reject(value));
Útil junto con .mockResolvedValueOnce() o para rechazar con diferentes excepciones en múltiples llamadas asíncronas:
- 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)
Acepta una función que se usará temporalmente como implementación del mock mientras se ejecuta el callback.
test('test', () => {
const mock = jest.fn(() => 'outside callback');
mock.withImplementation(
() => 'inside callback',
() => {
mock(); // 'inside callback'
},
);
mock(); // 'outside callback'
});
mockFn.withImplementation puede usarse independientemente de si el callback es asíncrono (devuelve un thenable) o no. Si el callback es asíncrono, se devolverá una promesa. Al esperar la promesa, se esperará al callback y se restablecerá la implementación.
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'
});
Propiedades Reemplazadas
replacedProperty.replaceValue(value)
Cambia el valor de una propiedad ya reemplazada. Es útil cuando quieres reemplazar una propiedad y luego ajustar su valor en pruebas específicas. Como alternativa, puedes llamar a jest.replaceProperty() múltiples veces en la misma propiedad.
replacedProperty.restore()
Restaura el valor original de la propiedad del objeto.
Ten en cuenta que replacedProperty.restore() solo funciona cuando el valor de la propiedad fue reemplazado con jest.replaceProperty().
La opción de configuración restoreMocks permite restaurar propiedades reemplazadas automáticamente antes de cada prueba.
Uso con TypeScript
Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →
Los ejemplos de TypeScript en esta página solo funcionarán como se documenta si importas explícitamente las APIs de Jest:
import {expect, jest, test} from '@jest/globals';
Consulta la guía de Primeros pasos para obtener detalles sobre cómo configurar Jest con TypeScript.
jest.fn(implementation?)
Los tipos correctos del mock se inferirán automáticamente si se pasa una implementación a jest.fn(). En muchos casos se omite la implementación. Para garantizar seguridad de tipos, puedes pasar un argumento de tipo genérico (ver también los ejemplos anteriores como referencia):
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>
Construye el tipo de una función mock, por ejemplo, el tipo de retorno de jest.fn(). Es útil si necesitas definir una función mock recursiva:
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>
El tipo de utilidad jest.Mocked<Source> devuelve el tipo Source envuelto con las definiciones de tipo de las funciones mock de 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();
// ...
});
Se pueden pasar tipos de clases, funciones u objetos como argumento a jest.Mocked<Source>. Si prefieres restringir el tipo de entrada, usa: jest.MockedClass<Source>, jest.MockedFunction<Source> o jest.MockedObject<Source>.
jest.Replaced<Source>
El tipo de utilidad jest.Replaced<Source> devuelve el tipo Source envuelto con las definiciones de tipo de las propiedades reemplazadas de 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?)
El método auxiliar mocked() envuelve los tipos del objeto source y sus miembros anidados con las definiciones de tipo de las funciones mock de Jest. Puedes pasar {shallow: true} como argumento options para deshabilitar el comportamiento de mock profundo.
Devuelve el objeto 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>
Construye el tipo de una clase o función espiada (es decir, el tipo de retorno de 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);
});
Se pueden pasar tipos de clase o función como argumento a jest.Spied<Source>. Si prefieres restringir el tipo de entrada, usa: jest.SpiedClass<Source> o jest.SpiedFunction<Source>.
Usa jest.SpiedGetter<Source> o jest.SpiedSetter<Source> para crear respectivamente el tipo de un getter o setter espiado.