Skip to main content

Testing

Introduction

Testing is one of the best things Hyper Fetch has to offer. With our architecture approach and focus on global singleton structure, our tests can be largely based on the configuration we prepare for our application. Thanks to this, the tests are no longer sensitive to micro changes (like changing endpoints or types). Everything here reacts and adapts to our tests or shows the appropriate error - they are easier to maintain and faster to write.


Benefits

  • Our setup is always up to date with the production solution
  • No duplication of the configurations and setups
  • Easy maintenance of the tests
  • Tests are faster to build

Isolation

Architecture solution makes global module out of builder. This way it will get mixed between test cases from different files if we run them in many workers. To prevent this we need to follow two steps for full isolation.

  1. Clear builder - use built-in method .clear() to make sure we initialize builder submodules and clear all it's changes.
  2. Clear node / runner cache - as for jest, you should use built-in method .resetModules() to clean builder global module and reinitialize it again. If you look for some libraries you can checkout your environment runner methods or try libraries like decache.

Example

In our approach we are using great mocking library msw and testing-library but this solution works with other libraries like Cypress. Thanks to it we can simulate the real requests and make our tests as close to production environment as we can. Together we can create really powerful flow that allow us to create tests with ease and fun.

You can create the utilities set that takes command and use its method, endpoint and types to create function that allow you to intercept request.

import { builder } from "../api/builder";
import { getUsers } from "../api";

// 'createInterceptor' is some custom method for handling intercepting in the tests we write
// In our internal test we used MSW as main intercepting layer
const getUsersInterceptor = createInterceptor(getUsers, {
data: [
{ name: "John", age: 18 },
{ name: "Matthew", age: 27 },
],
});

beforeEach(() => {
// We need to reset modules cache as builder is globally exported module
// This way it will not get mixed-up with other test cases running in parallel
jest.resetModules();
// Clean the environment to make sure it's isolated
builder.clear();
});

it("My test", async () => {
// Start interceptor listener
const mock = getUsersInterceptor();

// Handle test
renderApp();
expect(await screen.findByText(mock.data[0])).toBeVisible();
});