3
respostas

[Dúvida] Como testar erro?

 test("Deve lançar erro quando texto for vazio.", () => {
        const texto = "";
        const k = 2;

        const resultado = golombService.encode(texto, k);

        expect(() => {
            golombService.encode(texto, k);
        }).toThrow(ErroValidacao);

        expect(() => {
            golombService.encode(texto, k);
        }).toThrow("O campo texto é obrigatório!");
    });

O segundo "expect", caso eu mude a mensagem vai dar erro no teste. É com deixar hard code mesmo ou tem outra forma melhor?

3 respostas

Oi, Luidi! Que bom ver você praticando testes unitários, esse cuidado com o comportamento do código faz muita diferença na qualidade do software.

Manter mensagens de erro diretamente no teste (hardcoded) pode causar problemas de manutenção, pois qualquer ajuste gramatical na classe de serviço quebraria o teste, mesmo que a lógica continuasse correta.

Pra resolver isso, uma abordagem interessante é centralizar essas mensagens. Se você utiliza uma constante ou um objeto de mensagens no seu código de produção, pode importar esse mesmo objeto no seu arquivo de teste.

Uma forma de organizar seu teste:

  1. No arquivo da lógica (ex: golombService.js), defina as mensagens:
    const MENSAGENS_ERRO = {
    TEXTO_OBRIGATORIO: "O campo texto é obrigatório!"
    };

  2. No seu teste, você importa e utiliza essa referência:
    test("Deve lançar erro quando texto for vazio.", () => {
    const texto = "";
    const k = 2;

    expect(() => {
    golombService.encode(texto, k);
    }).toThrow(ErroValidacao);

    expect(() => {
    golombService.encode(texto, k);
    }).toThrow(MENSAGENS_ERRO.TEXTO_OBRIGATORIO);

});

se o texto da mensagem precisar mudar no futuro, você altera em apenas um lugar e o teste continua passando.

Outra dica: notei que no seu exemplo você chamou golombService.encode(texto, k) fora do expect logo no início. Se essa linha disparar o erro, o teste será interrompido antes de chegar nas verificações. Para testar exceções com Jest, basta manter a chamada apenas dentro da função anônima do expect, como você fez nos blocos seguintes.

Espero que isso ajude a deixar seus testes mais flexíveis. Continue com os bons estudos!

Alura Conte com o apoio da comunidade Alura na sua jornada. Abraços e bons estudos!

Quando o campo "texto" é um string vazia, null ou undefined eles tem a mesma mensagem de erro. A minha dúvida é: eu tenho q fazer os testes desses 3 casos mesmo assim? Ou é má prática?

test("Deve lançar erro quando texto for vazio", () => {
    const executar = () => golombService.encode("", 2);

    expect(executar).toThrow(ErroValidacao);
    expect(executar).toThrow(MENSAGENS_ERRO.CAMPO_OBRIGATORIO("texto"));
    });

    test("Deve lançar erro quando texto for undefined", () => {
        const executar = () => golombService.encode(undefined, 2);

        expect(executar).toThrow(MENSAGENS_ERRO.CAMPO_OBRIGATORIO("texto"));
    });

    test("Deve lançar erro quando texto for null", () => {
        const executar = () => golombService.encode(null, 2);

        expect(executar).toThrow(MENSAGENS_ERRO.CAMPO_OBRIGATORIO("texto"));
    });

Oi, Luidi!
Testar esses diferentes cenários (vazio, null e undefined) não é uma má prática. Na verdade, garante que sua validação lida corretamente com diferentes tipos de ausência de dado. No JavaScript, é comum que uma função se comporte de um jeito com uma string vazia e de outro com null, então verificar esses limites traz segurança.

Para evitar a repetição de código e manter seus testes limpos, você pode utilizar o test.each do Jest. Ele permite rodar o mesmo teste com diferentes valores de entrada.

olha como o seu código pode ficar mais direto:

describe("Validação do campo texto", () => {
    test.each([
        ["vazio", ""],
        ["undefined", undefined],
        ["null", null]
    ])("Deve lançar erro quando o texto for %s", (tipo, valor) => {
        const executar = () => golombService.encode(valor, 2);

        expect(executar).toThrow(ErroValidacao);
        expect(executar).toThrow(MENSAGENS_ERRO.CAMPO_OBRIGATORIO("texto"));
    });
});

Dessa forma, você mantém a cobertura completa para os três casos, mas escreve a lógica do teste apenas uma vez. Se no futuro a regra mudar, você só precisa mexer em um lugar.

Essa técnica ajuda a cobrir os chamados "edge cases" (casos de borda) sem poluir o arquivo de testes com blocos repetitivos.

Bons estudos e continue explorando essas ferramentas de automação!