Olá, Luidi!
Sobre sua última dúvida, o melhor jeito de fechar esse assunto é separar duas classificações diferentes:
- teste unitário vs teste de integração → isso depende de isolar ou não dependências reais.
- caixa preta vs caixa branca → isso depende de quanto o teste conhece da implementação.
Então, um teste não precisa ser 100% uma coisa só em todos os sentidos. Ele pode ser, por exemplo, unitário e ao mesmo tempo ter um grau de caixa branca.
Resumo corrigido no formato que você montou:
1. Um teste pode ser mais caixa preta ou mais caixa branca; isso não precisa ser absoluto.
Exemplo: se você chama cadastrarUsuario(data) e valida só o retorno ou o erro, sem olhar métodos internos, ele está mais para caixa preta.
2. Um teste de integração costuma ser mais próximo de caixa preta, porque usa dependências reais.
Exemplo: deixar Usuario.pegarPeloEmail() e salvar() acessarem o banco de verdade.
Você testa o fluxo completo sem substituir partes internas.
3. Um teste unitário não é sempre 100% caixa branca.
Exemplo: testar que cadastrarUsuario lança erro quando senha não foi enviada:
você valida só entrada e saída, sem precisar saber se existe salvar, hash ou pegarPeloEmail.
Isso é unitário e pode ser bem próximo de caixa preta.
4. Um teste unitário pode ter aspectos de caixa branca quando usa mock de uma dependência interna conhecida.
Exemplo: mockar Usuario.prototype.salvar.
Neste caso, para isolar a unidade, você precisou saber que cadastrarUsuario() chama salvar() internamente.
Então ele continua sendo unitário, mas com aspecto de caixa branca.
5. Mock não significa automaticamente caixa branca total.
Exemplo: às vezes você mocka uma dependência externa conhecida pelo contrato, sem acoplar o teste a muitos detalhes internos.
Quanto mais o teste depende de saber quem é chamado internamente, mais ele anda para a caixa branca.
6. Teste de integração normalmente não usa mock, mas pode usar em alguns cenários e continuar sendo integração.
Exemplo: testar service + banco real, mas mockar um envio de e-mail externo.
Ele continua sendo integração, porque ainda integra partes reais do sistema, só não todas.
7. Então o mais seguro é pensar em “grau” e não em rótulo rígido.
Um teste pode ser:
- unitário + mais caixa preta
- unitário + mais caixa branca
- integração + mais caixa preta
- integração + com algum aspecto de caixa branca
Aplicando ao seu caso:
- Sem mock e com banco real → teste de integração, mais próximo de caixa preta.
- Com mock de
salvar() e pegarPeloEmail() → teste unitário, com aspectos de caixa branca. - Testando só validação de entrada, como ausência de senha → teste unitário, bem próximo de caixa preta.
Veja este exemplo de teste unitário mais próximo de caixa preta:
it('deve lançar erro quando a senha não for enviada', async () => {
const data = {
nome: 'John Doe',
email: 'john@example.com'
};
await expect(authService.cadastrarUsuario(data))
.rejects
.toThrow('A senha de usuário é obrigatório!');
});
Neste caso, o teste não precisa saber que existe salvar() nem pegarPeloEmail().
Veja este exemplo de teste unitário com aspecto de caixa branca:
it('deve criptografar a senha antes de salvar', async () => {
const data = {
nome: 'John Doe',
email: 'john@example.com',
senha: 'senha123'
};
jest.spyOn(Usuario, 'pegarPeloEmail').mockResolvedValue(null);
const salvarSpy = jest
.spyOn(Usuario.prototype, 'salvar')
.mockImplementation(async function(usuario) {
return {
id: 1,
nome: usuario.nome,
email: usuario.email,
senha: usuario.senha
};
});
const resultado = await authService.cadastrarUsuario({ ...data });
expect(salvarSpy).toHaveBeenCalledTimes(1);
expect(resultado.content.senha).not.toBe('senha123');
});
Neste exemplo, para mockar salvar, você precisou conhecer a implementação.
Por isso ele tem aspecto de caixa branca.
Fechando em uma frase:
tipo de teste diz o que foi isolado; caixa preta/branca diz quanto da implementação o teste conhece.
Fico à disposição e peço perdão pela demora em responder!