Fixtures e interceptors
Los fixtures y los interceptors permiten simular datos de forma universal, sin necesidad de aplicar monkeypatching al comportamiento de fetch. Los fixtures definen respuestas estáticas para combinaciones específicas de argumentos de un endpoint. Esto permite usarlos en contextos estáticos como mockInitialState(). Los interceptors son funciones que se ejecutan y coinciden con un patrón de fetch. Esto los limita a usarse únicamente en contextos de respuesta dinámica como MockResolver.
SuccessFixture
Representa una respuesta exitosa
- Type
- With Generics
export interface SuccessFixture {
endpoint;
args;
response;
error?;
delay?;
}
export interface SuccessFixture<
E extends EndpointInterface = EndpointInterface,
> {
readonly endpoint: E;
readonly args: Readonly<Parameters<E>>;
readonly response:
| ResolveType<E>
| ((...args: Parameters<E>) => ResolveType<E>);
readonly error?: false;
/** Number of milliseconds to wait before resolving */
readonly delay?: number;
}
const countFixture = {
endpoint: new RestEndpoint({ path: '/api/count' }),
args: [],
response: { count: 0 },
};
ErrorFixtures
Representa una respuesta fallida o con error
- Type
- With Generics
export interface ErrorFixture {
endpoint;
args;
response;
error;
delay?;
}
export interface ErrorFixture<E extends EndpointInterface = EndpointInterface> {
readonly endpoint: E;
readonly args: Readonly<Parameters<E>>;
readonly response: any;
readonly error: true;
/** Number of milliseconds to wait before resolving */
readonly delay?: number;
}
const countErrorFixture = {
endpoint: new RestEndpoint({ path: '/api/count' }),
args: [],
response: { message: 'Not found', status: 404 },
error: true,
};
Interceptor
Los interceptors coinciden con una petición según su método testKey() y luego
calculan la respuesta de forma dinámica con el método response().
- Type
- With Generics
interface ResponseInterceptor {
endpoint;
response(...args);
delay?;
delayCollapse?;
}
interface FetchInterceptor {
endpoint;
fetchResponse(input, init);
delay?;
delayCollapse?;
}
type Interceptor = ResponseInterceptor | FetchInterceptor;
interface ResponseInterceptor<
T = any,
E extends EndpointInterface & {
update?: Updater;
testKey(key: string): boolean;
} = EndpointInterface & { testKey(key: string): boolean },
> {
readonly endpoint: E;
response(this: T, ...args: Parameters<E>): ResolveType<E>;
/** Number of milliseconds (or function that returns) to wait before resolving */
readonly delay?: number | ((...args: Parameters<E>) => number);
/** Waits to run `response()` after `delay` time */
readonly delayCollapse?: boolean;
}
interface FetchInterceptor<
T = any,
E extends EndpointInterface & {
update?: Updater;
testKey(key: string): boolean;
fetchResponse(input: RequestInfo, init: RequestInit): Promise<Response>;
extend(options: any): any;
} = EndpointInterface & {
testKey(key: string): boolean;
fetchResponse(input: RequestInfo, init: RequestInit): Promise<Response>;
extend(options: any): any;
},
> {
readonly endpoint: E;
fetchResponse(this: T, input: RequestInfo, init: RequestInit): ResolveType<E>;
/** Number of milliseconds (or function that returns) to wait before resolving */
readonly delay?: number | ((...args: Parameters<E>) => number);
/** Waits to run `response()` after `delay` time */
readonly delayCollapse?: boolean;
}
type Interceptor<T, E> = ResponseInterceptor<T, E> | FetchInterceptor<T, E>;
const incrementInterceptor = {
endpoint: new RestEndpoint({
path: '/api/count/increment',
method: 'POST',
body: undefined,
}),
response() {
return {
count: (this.count = this.count + 1),
};
},
delay: () => 500 + Math.random() * 4500,
};
Argumentos
endpoint
El endpoint con el que debe coincidir.
args
(Solo fixtures) Los argumentos con los que debe coincidir.
response(...args)
Determina cuál debe ser la respuesta de este mock. Si es una función, se ejecutará.
Ejecutar la función se llama 'colapsar', por el mecanismo de la mecánica cuántica
this se puede usar para almacenar datos simulados del lado del servidor. Se inicializa con getInitialInterceptorData. Es importante no usar funciones flecha al usar this, ya que no permiten el enlace de this.
fetchResponse(input, init)
Cuando se proporciona, construirá un método response() que se usará sobrescribiendo (mediante .extend) fetchResponse.
Simplemente devuelve el valor esperado, en lugar de una Response HTTP real.
const incrementInterceptor = {
endpoint: new RestEndpoint({
path: '/api/count/increment',
method: 'POST',
body: undefined,
}),
fetchResponse(input, init) {
return {
count: (this.count = this.count + 1),
updatedAt: JSON.parse(init.body).updatedAt,
};
},
};
Esto puede ser útil cuando quieres usar el body generado en un getRequestInit() personalizado
delay: number
Es el número de milisegundos que se espera antes de resolver la promesa. Puede ser útil para simular condiciones de carrera.
Cuando se envía una función, su valor de retorno se usa como el número de milisegundos.
delayCollapse: boolean
true: Ejecuta response() después del tiempo de delay
false: Ejecuta response() de inmediato y luego lo resuelve después del tiempo de delay
Puede ser útil para simular demoras de procesamiento del servidor.