Descomplicando: testes unitários
Quem sou?
Motivação
Descomplicando os testes
// Função para formatar a string para maiúsculo
function toUpper(message: string) {
return message.toUpperCase()
}
test("should return message formated", () => {
const message = toUpper("anyMessage")
expect(message).toBe("ANYMESSAGE")
})
Caso real de um teste
interface HttpRequest {
name: string
email: string
password: string
}
interface HttpResponse {
statusCode: number
body: any
}
class CreateUserController {
async handle(request: HttpRequest) {
if(!request.name || !request.email || !request.password)
return {
statusCode: 400
body: new Error("send all required fields")
}
return {
statusCode: 200,
body: "ok"
}
}
}
test("it should return 400 if no name is provided", async () => {
const createUserController = new CreateUserController()
const response = await createUserController.handle({
name: '',
email: 'anyEmail@mail.com',
password: 'anyPassword'
})
expect(response).toEqual({
statusCode: 400,
body: new Error("send all required fields")
})
})
test("it should return 400 if no email is provided", async () => {
const createUserController = new CreateUserController()
const response = await createUserController.handle({
name: 'anyName',
email: '',
password: 'anyPassword'
})
expect(response).toEqual({
statusCode: 400,
body: new Error("send all required fields")
})
})
test("it should return 400 if no password is provided", async () => {
const createUserController = new CreateUserController()
const response = await createUserController.handle({
name: 'anyName',
email: 'anyEmail@mail.com',
password: ''
})
expect(response).toEqual({
statusCode: 400,
body: new Error("send all required fields")
})
})
test("it should return 200 valid data is provided", async () => {
const createUserController = new CreateUserController()
const response = await createUserController.handle({
name: 'anyName',
email: 'anyEmail@mail.com',
password: 'anyPassword'
})
expect(response).toEqual({
statusCode: 200,
body: "ok"
})
})
Conclusão
Links
- Meus contatos Github Linkedin
- Matérial de estudo: A pirâmide de testes Uma ÚNICA Coisa Me Faz Programar “10x” Mais Rápido (De Verdade) Seu próximo back-end Node com TESTES! (+ SOLID)
Fala Carlos Vinicius! Muito massa seu post! Na mesma pegada de desenvolvimento testável e escrevendo uma arquitetura desacoplada, publiquei esse artigo sobre a utilização de um ORM no contexto testável e independente. No meu desenvolvimento guiado por testes, gosto muito de utilizar o factory pattern para o gerenciamento de entradas da minha função/classe. EX: Nesse mesmo contexto de teste de uma classe controller, gosto de configurar meu teste da seguinte maneira:
import { CreateUserController } from "./controller";
const makeHttpRequest = (props?: Partial<HttpRequest>): HttpRequest => ({
name: "any_name",
email: "any_email",
password: "any_password",
...props,
});
test("it should return 400 if no name is provided", async () => {
const createUserController = new CreateUserController();
const request = makeHttpRequest({ name: undefined });
const response = await createUserController.handle(request);
expect(response).toEqual({
statusCode: 400,
body: new Error("send all required fields"),
});
test("it should return 200 valid data is provided", async () => {
const createUserController = new CreateUserController();
const request = makeHttpRequest();
const response = await createUserController.handle(request);
expect(response).toEqual({
statusCode: 200,
body: "ok",
});
});
});
No exemplo acima, a função makeHttpRequest
monta a minha requisição com todos os parâmetros válidos, e se eu quiser sobrescrever algum parâmetro, eu passo na chamada da função, como estou fazendo no primeiro teste. Isso me ajuda a manter o teste mais legível e com menos repetições.
Da mesma maneira, no segundo teste, eu não preciso passar nenhum parâmetro, pois a função makeHttpRequest
já monta a requisição com todos os parâmetros válidos.
Espero que ajude! Abraço!
Eu sofro na hora dos testes unitarios kkk
eu realmente gostei do artigo e se puder criar un artigo sobre as outras camadas... principalmente a de servicos, ficaria feliz em ler :)
obrigada pelo conteudo
Deixa eu te perguntar, você tem alguma dica para fazer testes envolvendo mockar APIs de terceiros e comunicação com Redis?
Porque eu tenho um caso que preciso em um o nestjs que tem muitas etapas, muitas trechos código que precisam de todo um contexto no Redis para conseguir chegar no estado válido que eu quero testar.
Olá Carlos, preciso e quero começar certo, estou no inicio de front e quero entender mais e saber implementar testes unitários nos meus códigos, por onde eu começo? Documentação de como fazer? Valeu o post.