Saltar al contenido principal
Versión: 29.7

Funciones Mock

Traducción Beta No Oficial

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.

Traducción Beta No Oficial

Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →

información

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()

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.

precaución

¡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.

información

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.

consejo

jest.fn(implementation) es una forma abreviada de jest.fn().mockImplementation(implementation).

const mockFn = jest.fn(scalar => 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:

SomeClass.js
module.exports = class SomeClass {
method(a, b) {}
};
SomeClass.test.js
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);

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.

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

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.

const mock = jest.fn();

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.

const mockFn = jest
.fn()
.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:

test('async test', async () => {
const asyncMock = jest.fn().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:

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'
});

mockFn.mockRejectedValue(value)

Forma abreviada de:

jest.fn().mockImplementation(() => Promise.reject(value));

Útil para crear funciones simuladas asíncronas que siempre rechazarán:

test('async test', async () => {
const asyncMock = jest
.fn()
.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:

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'
});

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

Traducción Beta No Oficial

Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →

información

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.

src/utils.ts
export function isLocalhost(): boolean {
return process.env['HOSTNAME'] === 'localhost';
}
src/__tests__/utils.test.ts
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.

song.ts
export const song = {
one: {
more: {
time: (t: number) => {
return t;
},
},
},
};
song.test.ts
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()).

__utils__/setDateNow.ts
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.