Consegue me dar um exemplo com a função "criarUsuario"(que cria e chama a função salvar para guardar no banco) fazendo um teste unitário e um teste de integração e explicando cada um?
Consegue me dar um exemplo com a função "criarUsuario"(que cria e chama a função salvar para guardar no banco) fazendo um teste unitário e um teste de integração e explicando cada um?
Oii, Luidi.
Vamos imaginar um cenário onde temos uma função criarUsuario. Ela recebe os dados, valida e depois chama uma função salvar (que interage com o banco de dados).
No teste unitário, o foco é exclusivamente na lógica da função criarUsuario. Não queremos saber se o banco de dados está funcionando ou se a função salvar realmente grava algo. Queremos apenas garantir que criarUsuario processa os dados e tenta salvar.
Aqui, geralmente usamos o jest.fn() para substituir a função salvar por um dublê completo.
// Exemplo conceitual de Teste Unitário
const salvarNoBanco = jest.fn(); // Dublê total
test('Deve chamar a função salvar ao criar um usuário válido', () => {
const usuario = { nome: 'Luidi', email: 'luidi@email.com' };
criarUsuario(usuario, salvarNoBanco);
expect(salvarNoBanco).toHaveBeenCalledWith(usuario);
});
Exemplo de teste de integração:
No teste de integração, o objetivo é verificar se as diferentes partes do sistema (a lógica e o banco de dados) estão conversando corretamente. Aqui, o jest.spyOn() é muito útil porque ele permite que a função original seja executada enquanto nós apenas observamos a comunicação.
criarUsuario, os dados realmente chegam e permanecem no banco de dados (ou em uma simulação do banco que se comporta como o real).salvar é executada de verdade.// Exemplo conceitual de Teste de Integração
const db = require('./database');
const spySalvar = jest.spyOn(db, 'salvar'); // Espiona o método real
test('Deve garantir que o usuário foi registrado no banco', async () => {
const usuario = { nome: 'Luidi', email: 'luidi@email.com' };
await criarUsuario(usuario);
// O spy confirma que a integração aconteceu
expect(spySalvar).toHaveBeenCalled();
// Verificamos o resultado real no banco
const usuarioNoDb = await db.buscarPorEmail('luidi@email.com');
expect(usuarioNoDb.nome).toBe('Luidi');
});
Diferenças no fluxo de execução:
Pra facilitar a memorização, veja como o fluxo de dados se comporta em cada caso:
| Característica | Teste Unitário | Teste de Integração |
|---|---|---|
| Escopo | Apenas uma função ou componente. | A união de vários componentes. |
| Velocidade | Muito rápido (não acessa recursos externos). | Mais lento (acessa banco, rede ou arquivos). |
| Ferramenta comum | jest.fn() (Substituição total). | jest.spyOn() (Observação do real). |
| Objetivo | Validar a lógica isolada. | Validar a comunicação entre as partes. |
No teste unitário, você usa o mock para "fingir" que o banco de dados existe, focando na regra de negócio. No teste de integração, você usa o espião ou a função real para garantir que, quando o código sai da sua função, ele chega corretamente ao destino final.