DEV Community

Cover image for Mock isolated service in a React Application
Miguel
Miguel

Posted on • Updated on

Mock isolated service in a React Application

The term division to conquer was used throughout history in political and political ideals, consisting of the fragmentation of powers, thus, it is a strategy that aims to break or accompany between social structures and take them independently.

"Divide and Conquer. - Júlio César"

Hi guys, how are you today?

Based on the divide and conquer principle, i am writing this post to demonstrate how it is possible to isolate services in a react application and test them independently.

Step one: Understanding the structure

structure

Adapters work as a bridge to the outside world, this is done through external functions or developed interfaces.

Services are a similar construct used by the repository pattern often used by the backend to build a superficial and literal layer between code and database.

Entities are interfaces and literal representations of the members of our application.

Step two: Building an adapter

import axios from "axios";

const api = axios.create({
  baseURL: process.env.API_BASE,
});

export default api;

Enter fullscreen mode Exit fullscreen mode
/adapters/api.ts

The code above is very simple, we are just creating a new instance of axios and exporting it to the rest of the application.

Third step: Assembling the entity

The entity is just a type with its respective attributes.

export type TUser = {
  name: string;
  email: string;
};
Enter fullscreen mode Exit fullscreen mode
/entities/user.ts

Last step: Finally the services

export const registerUser = (user: TUser) => {
  return api.post("api/user", user);
}

export const getUser = (id: number) => {
  return api.get(`api/user/${id}`, user);
}
Enter fullscreen mode Exit fullscreen mode
/services/user.ts

Ui

Our ui is composed of two inputs and a button with their respective data-testid

<Input data-testid="inputName" />
<Input data-testid="inputEmail" />
<Button data-testid="submit" type="submit">Save</Button>
Enter fullscreen mode Exit fullscreen mode

Writing the tests

First let's mock the service

import * as user from "/services/user.ts";

jest.spyOn(user, "registerUser").mockImplementation(() =>
   Promise.resolve({
      message: "created"
   })
);
Enter fullscreen mode Exit fullscreen mode

The magic is in the code above, we are exporting the entire service file and telling spyOn to look at it as a function object

it("Must submit a new user", async () => {
  const { getAllByTestId } = render(<User />);

  const name = getAllByTestId("inputName")[0] as   HTMLInputElement;
  const email = getAllByTestId("inputEmail")[0] as HTMLInputElement;
  const submit = getAllByTestId("submit");

  fireEvent.change(email, { target: { value: "email@email.com" } });
  fireEvent.change(name, { target: { value: "Miguel" } });
  fireEvent.submit(submit);
  await waitFor(() => 
        expect(user.registerUser).toHaveBeenCalledTimes(1));
  });
Enter fullscreen mode Exit fullscreen mode

In this case we expect our form to call our registration function at least once.

And we reached the end of the tests, the big point is in the import of the service that will be a mock. Take a good look at how the spy function works.

Naruto

Time is very important, thanks for sharing a little bit of yours with me 😊.

image

Discussion (0)