Eu tenho um monte de classes que lidam com validação de valores. Por exemplo, uma RangeValidator
classe verifica se um valor está dentro do intervalo especificado.
Toda classe de validador contém dois métodos is_valid(value)
:, que retorna True
ou False
depende do valor, e ensure_valid(value)
que verifica um valor especificado e não faz nada se o valor for válido ou lança uma exceção específica se o valor não corresponder às regras predefinidas.
Atualmente, existem dois testes de unidade associados a este método:
Aquele que passa um valor inválido e garante que a exceção foi lançada.
def test_outside_range(self): with self.assertRaises(demo.ValidationException): demo.RangeValidator(0, 100).ensure_valid(-5)
Aquele que passa um valor válido.
def test_in_range(self): demo.RangeValidator(0, 100).ensure_valid(25)
Embora o segundo teste faça seu trabalho - falha se a exceção é lançada e é bem-sucedido se ensure_valid
não lança nada - o fato de não haver assert
s dentro parece estranho. Alguém que lê esse código imediatamente se pergunta por que existe um teste que parece não estar fazendo nada.
Essa é uma prática atual ao testar métodos que não retornam um valor e não têm efeitos colaterais? Ou devo reescrever o teste de uma maneira diferente? Ou simplesmente faça um comentário explicando o que estou fazendo?
fonte
self
referência) e não retorna resultado, não é uma função pura.void
em muitos idiomas e tem regras tolas). Como alternativa, você pode ter um número infinito loop (que funciona mesmo quando "não retorna resultados" realmente significa que não retorna resultados).unit -> unit
em qualquer idioma que considera a unidade um tipo de dados padrão em vez de algo magicamente especial. Infelizmente, apenas retorna a unidade e não faz mais nada.Respostas:
A maioria das estruturas de teste possui uma asserção explícita para "Não lança", por exemplo, Jasmine possui
expect(() => {}).not.toThrow();
nUnit e amigos também.fonte
Isso depende fortemente da linguagem e da estrutura usada. Falando em termos de
NUnit
, existemAssert.Throws(...)
métodos. Você pode passar a eles um método lambda:que é executado dentro do
Assert.Throws
. A chamada para o lambda provavelmente será encerrada por umtry { } catch { }
bloco e a asserção falhará, se uma exceção for capturada.Se sua estrutura não fornecer esses meios, você poderá contornar isso, encerrando a chamada sozinho (estou escrevendo em C #):
Isso torna a intenção mais clara, mas desordena o código em certa medida. (É claro que você pode agrupar todas essas coisas em um método.) No final, tudo depende de você.
Editar
Como Doc Brown apontou nos comentários, a questão não foi indicar que o método lança, mas que não lança. No NUnit, há também uma afirmação para que
fonte
Basta adicionar um comentário para deixar claro por que nenhuma afirmação é necessária e por que você não a esqueceu.
Como você pode ver nas outras respostas, qualquer outra coisa torna o código mais complicado e confuso. Com o comentário lá, outros programadores saberão a intenção do teste.
Dito isto, esse tipo de teste deve ser uma exceção (sem trocadilhos). Se você estiver escrevendo algo assim regularmente, provavelmente os testes estão dizendo que o design não é o ideal.
fonte
Você também pode afirmar que alguns métodos são chamados (ou não chamados) corretamente.
Por exemplo:
No seu teste:
fonte