Qual é o objetivo de Verifiable () no Moq?

125

Qual é o propósito Verifiable()?

Se eu verificar um Mocke deixar isso de fora, ele ainda verificará o SetUp.

Edit: Eu estava usando, VerifyAll()portanto, o motivo de tudo estar sendo verificado. Depois de mudar para Verify()apenas meus .Verifiable() SetUps estavam sendo verificados.

Castrohenge
fonte

Respostas:

83

ADENDO: Como a outra resposta afirma, o objetivo .Verifiableé incluir a Setupem um conjunto de " Verify(...)chamadas adiadas " que podem ser acionadas via mock.Verify().

O esclarecimento do OP deixa claro que esse era o objetivo e o único problema era descobrir por que não estava funcionando, mas, como estimulado o @Liam, a resposta também deveria estar relacionada a isso: - Os principais casos de uso, tanto quanto possível veja são:

  • mantendo DRYness entre um mock.Setup()emock.Verify
  • permitindo desconectar a configuração de uma verificação da própria Verifychamada (por exemplo, você pode configurá-la em outro método auxiliar)

... e voltando à minha resposta, que diz de maneira concisa e eficaz: "tenha cuidado, pois os profissionais acima são geralmente considerados superados pelo efeito que a consecução desses objetivos tem na legibilidade e manutenção de testes que se apoiam demais nessas construções"

ORIGINAL: Observe que, sempre que possível, deve-se seguir o layout AAA e, portanto, deve-se fazer mock.Verify( expression )chamadas explícitas após a conclusão do trabalho, em vez de mock.Setup( ... ).Verifiable()emparelhar com um mock.Verify()oumock.VerifyAll() sempre que possível (crédito: @kzu ).

Ruben Bartelink
fonte
7
@EricSmith Olhando para trás, não pense que eu coloquei o suficiente. Há muito mais benefícios em dividir seu trabalho em empacotamento AAA do que concentrar-se demais em pontos comuns entre as fases Organizar e Afirmar. 90% do tempo, há algo a ser ganho com as nuances de como você expressa as chamadas do Verify no final; portanto, dedique muito tempo para otimizar isso, mesmo que, em alguns casos, pareça uma duplicação dolorosa. Um dos pontos que manning.com/osherove faz muito bem é que fazer um teste faz sentido para alguém que está entrando é fundamental - então fique com a convenção!
Ruben Bartelink
3
Normalmente, eu não sou do tipo contrário à sabedoria aceita, mas ainda não estou convencido dos benefícios do AAA vs Verifyable()/ VerifyAll()em todos os casos. Meu teste de unidade atual tem um grande número de Setup(...)chamadas (> 30). Pode corresponder a cada um deles com um Verify () equivalente para atender à convenção, mas isso causa uma grande quantidade de duplicação de código e será mais difícil de manter e ler à medida que o número de testes de unidade aumenta. Eu acho que o que realmente estou perguntando é que podem ser feitas exceções se houver um grande número de configurações ou evitar Verifiable()uma regra rígida e rápida?
Steve Chambers
5
@SteveChambers Um elemento-chave da AAA é que não é A * - deve haver um único ato e uma única declaração. Portanto, enquanto você está tecnicamente correto ao dizer que é menos código para você, as coincidências de quais de suas configurações se aplicam a quais (sub) atos e (sub) afirmações se tornarão invariavelmente um campo minado. Portanto, não, não é difícil e rápido, mas eu diria que sugerir que é quase 50:50 seria um péssimo conselho. (Observe também que você não precisa fazer uma instalação para fazer uma verificação, a menos que esteja tentando introduzir um comportamento específico durante a lei - que é outro elemento de testes claros)
Ruben Bartelink
1
@Liam E é realmente muito bom que você ainda esteja convencido de que é uma ferramenta apropriada para o seu trabalho - o que realmente quero dizer é que ela é desaprovada como uma abordagem geral para escrever testes com zombarias - ou seja, apesar do fato de que ela alcança DRYness perfeitamente entre um Setupe um Verify, que pode estar faltando um maior vitória viável só pode ser relaxante a restrição DRY da maneira sugerida pela AAA e da família de estratégias que implica fortemente
Ruben Bartelink
1
@ Liam Obrigado pelo estímulo; Eu atualizei minha resposta porque você está correto no que está fazendo. No dia em que respondi a perguntas como essa, minha visão geralmente era afirmar sucintamente uma resposta atômica e permitir que respostas concorrentes como a outra preenchessem o mapa. Hoje em dia (se eu ainda tivesse tempo para responder a perguntas), provavelmente tentaria dar a resposta mais completa que isso se tornou em primeira instância.
Ruben Bartelink
54

Quando o Verify()método é chamado no final do teste, se alguma das expectativas marcadas como verificáveis ​​não tiver sido chamada, uma exceção será thrown.

VerifyAll() não verifica se há expectativas verificáveis.

Suvesh Pratapa
fonte
você se importaria de explicar um pouco mais sobre o VerifyAll () não verificar expectativas verificáveis?
JW
@JW Significa que VerifyAll verifica todas as configurações sem considerar se elas foram marcadas como expectativas verificáveis.
Phoog 24/10/19