I needed to test the presence of a "loading-indicator" in a widget that posted data.
Usually I would have done this with window.setTimeout
or something similar: The timeout
simulates the time it takes to complete the network call. But I find that running the whole
test suite for my application takes a long time, and I wanted to avoid these
arbitrary timeout lengths.
Instead I wanted more control of when the loading is done: What if I could hold onto the
"loading"-phase in the application until the exact moment I was done checking the presence
of the loading-indicator? In Jest, I want to simply tell it that loadingIsDone()
and then
continue testing that application state is correct after loading.
Therefore I made this simple utility. When calling mockLatency
,
it returns a function startLoading
and a resolver completeLoading
.
startLoading
I typically feed to the mocked implementation of axios, and when I
am done testing the "loading phase" of the application, I can call completeLoading
and test the "done" phase of the application.
This means no more of this shenanigans:
mockedAxios.post.mockImplementationOnce(new Promise(r => setTimeout(r, 300)));
// TEST LOADING PHASE HERE
await act(async function() {
// Wait for be sure the 300ms has ellapsed before testing further
await new Promise(r => setTimeout(r, 300))
});
// TEST AFTER LOADING HERE
Instead you can do like this:
let { completeLoading, startLoading } = mockLatency();
mockedAxios.post.mockImplementationOnce(startLoading);
// TEST LOADING PHASE HERE
await act(async function() {
await completeLoading(1);
});
// TEST AFTER LOADING HERE
As you can see, this saves 0 lines of code, but I would say that the code is somewhat more readable, and I know by experience that my tests runs faster.