Mock isolated service in a React Application
Miguel
Posted on January 25, 2022
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
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;
/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;
};
/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);
}
/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>
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"
})
);
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));
});
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.
Posted on January 25, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.