Mocking
Mocking is a built-in feature of Request. It is a feature that allows for mock the response for a given endpoint at the same time keeping the complete request lifecycle and events. Thanks to the design of the library, we can also micro-manage things like upload/download progresses, timings, trigger all kinds of errors for amazing developer experience. It is a great way to test your code in isolation, without relying on external services and keeping the full type safety of your code.
- Control upload/download progress and timings
- Simulate errors and timeouts
- Test edge cases and custom scenarios
- Keep your tests fast, reliable, and independent
How it works?
To add a mock to a request, we need to use the setMock(mockFn, config)
method. It accepts a function that returns a
mock response. With this simple concept you're able to introduce any mocking approach of your choice.
Method setMock()
is the only method modifying the Request reference.
This will allow us to mock every request in given group.
Options
What you return from the mocker is used to generate the output and behavior of the mocker.
Response
The base API requires you to return the response for the mocked request. This part defines how our data will look like.
PartialBy<Omit<ResponseType<Response, Error, AdapterType>, (data | error | responseTimestamp | requestTimestamp)>, (extra | success)> & ({ data: Response; error?: Error } | { data?: Response; error: Error })
Config
There is also additional config which can specify behavioral aspect of the mocker. How long it should be processed, should it throw timeout error or how much of a data we want to mock for the transfer updates.
Name | Type | Description |
---|---|---|
requestTime |
| Simulates how long the request to the server should take (in milliseconds) |
responseTime |
| Indicates how long the response from the server should take (in milliseconds). If their combined total takes longer than provided timeout, each value will be automatically adjusted to last half of the timeout time |
timeout |
| Informs how long the request should take before returning a timeout error (in milliseconds) |
totalDownloaded |
| total number of 'bytes' to be downloaded. |
totalUploaded |
| total number of 'bytes' to be uploaded. |
const request = client
.createRequest()({ endpoint: "shared-base-endpoint" })
.setMock(
() => {
// Data part
return {
data: { mocking: "is fun" },
status: 200,
};
},
{
// Config part
requestTime: 40,
responseTime: 60,
totalUploaded: 1000,
totalDownloaded: 1000,
},
);
In the example above - the request phase will take 40 milliseconds and during this phase 1000 'bytes' will be "uploaded"
(and onUploadProgress
events will be emitted). The response phase will take 60 millisecond and during this phase 1000
'bytes' will be "downloaded" (and onDownloadProgress
events will be emitted). In fact no data-exchange occurs, but we
will make sure to simulate it for you.
Usage and use cases
Request context
The mocker is now used by passing a callback function to setMock
. This function receives the request context and
returns the mock response. This allows for dynamic mocking, dependent on the passed arguments during execution.
const mockedRequest = client
.createRequest()({ endpoint: "/users/:id" })
.setMock(({ request }) => {
const { params } = request;
if (params.id === 11) {
return { data: [1, 2, 3], config: { status: 222 } };
}
return { data: [4, 5, 6], status: 200 };
});
The passed method may also be asynchronous:
const mockedRequest = client
.createRequest<{ response: Record<string, any> }>()({ endpoint: "users/:id" })
.setMock(async (request) => {
// Do some asynchronous processing of the payload
const myData = await processPayload(request.payload);
return { data: myData, status: 200 };
});
Note: Only the callback function form is supported. Passing objects, arrays, or lists of functions is no longer available.
Canceling
Canceling a request works the same way as in the real request. It will throw an error and the request will be canceled.
Timeout
You can simulate timeout error by setting timeout
to true
in the config.
Mocking state
Apart from adding a mock to a request, you can also remove it or disable it.
How to remove mocker?
If you need to remove the mocker from a request, use the clearMock()
method. This way mocker is disabled and mock data
is removed.
request.clearMock();
Disabling single mocker
Instead of removing mocker, you can also disable mocker and enable mocker at will with the request.setMockingEnabled
method. This way if you set mocking data, it will be kept and not removed as in the clearMock
case.
const mockedRequest = request.setMock({ data: fixture }); // mock is set
... // Here mocker works as usual
mockedRequest.setMockingEnabled(false); // Mocker is disabled
... // Request works as usual
mockedRequest.setMockingEnabled(true); // Mocker is enabled once again
Disabling mocking for all requests
If you want to disable mocking for all requests of a given client
instance - you can use the
client.setMockingEnabled
method. This way all related requests will behave 'as usual' and setting/enabling mocks on
single requests will not have any effect.
const client = new Client(...);
const mockedRequest_1 = newClient.createRequest()({ ... }).setMock({ data: fixture1 });
const mockedRequest_2 = newClient.createRequest()({ ... }).setMock({ data: fixture2 });
... // Here mocked requests return mocked data.
client.setMockingEnabled(false) // All mocks are disabled
... // Here requests work as usual
client.setMockingEnabled(true) // All mocks are enabled once again