1
resposta

teste unitário e integrado

Estou com dúvidas sobre até onde posso afirmar que meu teste é unitário e a partir de quando posso considerá-lo um teste integrado.

Estou desenvolvendo uma API e comecei a realizar testes. Em um deles, utilizei um mock para testar o serviço, enquanto no outro utilizei o retorno real do banco de dados. Não tenho certeza sobre qual opção devo continuar utilizando. Devo prosseguir salvando no banco de dados e verificando o retorno, ou devo criar um mock para simular o retorno do meu serviço?

No teste abaixo, estou usando o TypeORM, repositórios, model/service e controller.

Pelo que eu entendi, o primeiro teste abaixo é um teste unitário porque ele testa apenas um "arquivo", no caso, a função de criar, e eu retorno um valor. Já o outro é um teste integrado porque eu utilizo dois arquivos e dois métodos.

minhas afirmações estão certas sobre os exmplos a baixo ???

----- teste unitario ------

import { User } from "../../src/entities/user/User"; import { CreateUserService } from "../../src/model/user/CreateUserService"; import { IUsersRepository } from "../../src/repositories/IUsersRepositories"; import { beforeAll, describe, expect, it, jest } from "@jest/globals"; import { v4 as uuidv4 } from 'uuid'; import { mockAddAccountParams, mockUserModel } from "../common/TestUtilUser";

type u = { email: string; password: string; name: string; id: string; };

// Mock the repository const mockUsersRepository: jest.Mocked = { create: jest.fn(), exists: jest.fn(), get:jest.fn(), update:jest.fn(), delete:jest.fn(), addRolePermission:jest.fn(), // Add any other methods that your repository interface has };

describe("Create user", () => { let createUserService: CreateUserService;

beforeAll(() => { createUserService = new CreateUserService(mockUsersRepository); });

it("should be able to create a new user", async () => { mockUsersRepository.create.mockImplementation((async (user: User) => ({ ...user, id: uuidv4(), // Assign a unique identifier }))) const result = await createUserService.execute(mockAddAccountParams);

// The result is a User
expect(result).toHaveProperty("id");
expect(result.email).toBe("teste@gmail.com");

});

it("should not be able to create an existing user", async () => { const userData: User = { name: "teste", password: "teste", email: "tesaf@gmail.com", roles: [], permissions: [], id: "", created_at: new Date(), };

// Mock the behavior of the repository's methods as needed
mockUsersRepository.exists.mockResolvedValue(true);

await expect(createUserService.execute(userData)).rejects.toEqual(
  new Error("User already exists!")
);

// Optionally, you can make assertions on the mock's method calls

/* expect(mockUsersRepository.exists).toHaveBeenCalledWith("tesa@gmail.com"); expect(mockUsersRepository.create).not.toHaveBeenCalled(); */ }); });

------ Teste Integrado ----

import { beforeAll,afterAll, expect, it, describe } from '@jest/globals';

import { AppDataSource } from '../../src/database/data-source'; import { User } from "../../src/entities/user/User"; import { CreateUserService } from "../../src/model/user/CreateUserService" import { IUsersRepository } from "../../src/repositories/IUsersRepositories"; import { TypeormUsersRepository } from '../../src/repositories/typeorm/TypeormUsersRepository';

describe('Testando configDB', () => { let usersRepository: IUsersRepository; let createUserService: CreateUserService;

beforeAll(async () => { await AppDataSource.initialize(); // Ensure that the database connection is successful usersRepository = new TypeormUsersRepository(); createUserService = new CreateUserService(usersRepository); });

it('d', async () => { const userData: User = { name: "teytytste", password: "teyste", email: "testtye@gmail.com", roles: [], permissions: [], id: '', created_at: new Date(), };

const user = await createUserService.execute(userData);

expect(user).toHaveProperty("id");

});

afterAll(async () => { await AppDataSource.close(); // Close the database connection after all tests }); });

https://github.com/joaoribeiro20/API-REST_E-commerce_Server
1 resposta

E aí! Vamos lá:

Primeiro, você tá no caminho certo em querer entender a diferença entre teste unitário e teste integrado. A distinção entre eles é fundamental pra manter a qualidade dos seus testes e garantir que você está cobrindo todos os cenários necessários.

Teste Unitário:

Na definição clássica, um teste unitário é aquele que testa uma unidade isolada de código. No seu exemplo, você está mockando o repositório (mockUsersRepository) e focando apenas na função create do serviço CreateUserService. Isso é bom! Você não está preocupado com o banco de dados real ou outras dependências, só quer saber se a função de criação do usuário tá funcionando como esperado. Então, sim, esse é um teste unitário.

Teste Integrado:

O teste integrado, por outro lado, testa a interação entre diferentes partes do sistema. No seu segundo exemplo, você tá inicializando uma conexão com o banco de dados real e testando a criação de um usuário usando essa conexão real. Aqui, você quer garantir que a sua lógica de negócio e a integração com o banco de dados estão funcionando juntas corretamente. Portanto, esse é um teste integrado.

Sobre suas afirmações:

  • Teste Unitário: Você tá certo! Você está focando em uma função específica (create), mockando as dependências necessárias e testando se ela cria um usuário como esperado.

  • Teste Integrado: Também tá certo! Você tá integrando a lógica do serviço com o banco de dados real e verificando se a criação do usuário funciona corretamente.

Dicas:

  1. Quando usar Mocks? - Use mocks em testes unitários para isolar a unidade de código que você está testando. Isso deixa o teste mais rápido e menos propenso a falhas por causa de outras partes do sistema.

  2. Quando usar o Banco Real? - Use testes integrados quando você realmente precisa verificar como diferentes partes do sistema interagem, especialmente com o banco de dados. Mas lembre-se, esses testes geralmente são mais lentos e podem ser mais difíceis de configurar.