Skip to main content

Fixtures and Interceptors

Fixtures and Interceptors allow universal data mocking without the need for monkeypatching fetch behaviors. Fixtures define static responses to specific endpoint arg combinations. This allows them to be used in static contexts like mockInitialState(). Interceptors are functions run and match a fetch pattern. This restricts them to being used only in dynamic response contexts like MockResolver.

SuccessFixture

Represents a successful response

export interface SuccessFixture {
endpoint;
args;
response;
error?;
delay?;
}
const countFixture = {
endpoint: new RestEndpoint({ path: '/api/count' }),
args: [],
response: { count: 0 },
};

ErrorFixtures

Represents a failed/errored response

export interface ErrorFixture {
endpoint;
args;
response;
error;
delay?;
}
const countErrorFixture = {
endpoint: new RestEndpoint({ path: '/api/count' }),
args: [],
response: { message: 'Not found', status: 404 },
error: true,
};

Interceptor

Interceptors will match a request based on its testKey() method, then compute the response dynamically using the response() method.

interface ResponseInterceptor {
endpoint;
response(...args);
delay?;
delayCollapse?;
}

interface FetchInterceptor {
endpoint;
fetchResponse(input, init);
delay?;
delayCollapse?;
}

type Interceptor = ResponseInterceptor | FetchInterceptor;
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,
};

Arguments

endpoint

The endpoint to match.

args

(Fixtures only) The args to match.

response(...args)

Determines what the response for this mock should be. If a function it will be run.

Function running is called 'collapsing' after the mechanism in Quantum Mechanics

this can be used to store simulated server-side data. It is initialized using getInitialInterceptorData. It's important to not use arrow functions when using this as they disallow this binding.

fetchResponse(input, init)

When provided, will construct a response() method to be used based on overriding (by calling .extend) fetchResponse.

Simply return the value expected, rather than an actual HTTP Response.

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,
};
},
};

This can be useful when you want to use the body generated in a custom getRequestInit()

delay: number

This is the number of miliseconds to wait before resolving the promise. This can be useful when simulating race conditions.

When a function is sent, its return value is used as the number of miliseconds.

delayCollapse: boolean

true: Runs response() after delay time

false: Runs response() immediately, then resolves it after delay time

This can be useful for simulating server-processing delays.