Como verificar se o método NÃO foi chamado no Moq?


466

Como verifico que o método NÃO foi chamado no Moq ?

Tem algo como AssertWasNotCalled?

ATUALIZAÇÃO: A partir da versão 3.0, uma nova sintaxe pode ser usada:

mock.Verify(foo => foo.Execute("ping"), Times.Never());

Respostas:


155

ATUALIZAÇÃO : Desde a versão 3, verifique a atualização da pergunta acima ou a resposta de Dann abaixo.

Ou, faça com que o seu mock seja estrito, para que ele falhe se você chamar um método para o qual você não espera

new Mock<IMoq>(MockBehavior.Strict)

Ou, se você quiser que seu mock seja solto, use o .Throws (Exception)

var m = new Mock<IMoq>(MockBehavior.Loose);
m.Expect(a => a.moo()).Throws(new Exception("Shouldn't be called."));

9
... ou Callback () para definir algum sinalizador que possa ser afirmado.
alex

2
Também com a opção 2, você não pode ter um VerifyAll em um método geral de desmontagem - falhará dizendo que a expectativa não foi atendida; quando o teste deve passar idealmente.
Gishu 30/09/09

51
Este não é realmente um "verificar não chamado", pois poderia ser detectado dentro do método e ainda funcionaria - fornecendo um falso positivo!
Dan

4
Agora, a expectativa foi preterida
Tomasz Sikora

5
Essa pode ter sido a melhor maneira possível em 2009, mas certamente não agora. desculpe
Fabio Milheiro

537

Execute uma verificação após o teste com um Times.Neverconjunto de enumerações. por exemplo

_mock.Object.DoSomething()
_mock.Verify(service => service.ShouldntBeCalled(),Times.Never());

4
O que é crítico aqui é que a chamada Verificar (ação, Nunca) é após a chamada para a simulação. Eu pensei que estava montando a verificação para chamar VerifyAll () mais tarde (que não trabalho)
piers7

Simples e eficaz. Obrigado.
21818 Ian Grainger

45

Roubado de: John Foster respondeu à pergunta "Precisa de ajuda para entender melhor o Moq"

Uma das coisas que você pode querer testar é que o método de pagamento não é chamado quando uma pessoa com mais de 65 anos passa para o método

[Test]
public void Someone_over_65_does_not_pay_a_pension_contribution() {

    var mockPensionService = new Mock<IPensionService>();

    var person = new Person("test", 66);

    var calc = new PensionCalculator(mockPensionService.Object);

    calc.PayPensionContribution(person);

    mockPensionService.Verify(ps => ps.Pay(It.IsAny<decimal>()), Times.Never());
}

10

Isso não funciona nas versões recentes do Moq (desde pelo menos 3,1), ele deve ser especificado no Verifymétodo conforme mencionado na resposta.

Na verdade, é melhor especificar .AtMost(0)após a instrução Returns.

var m = new Mock<ISomething>();
m.Expect(x => x.Forbidden()).Returns("foo").AtMost(0);

Embora os "lances" também funcionem, AtMost(0)é IMHO mais expressivo.


-5

Use .AtMostOnce ();

Após o teste real, chame o método novamente. Se lançar uma exceção, foi chamado.


1
Não é um pouco obscuro afirmar que a exceção foi lançada pela estrutura de zombaria?
alex

Por quê? Basta verificar o tipo da exceção. Se alguém jogou meu Moq, você está seguro.
23414 Aaron Digulla

8
Usando Verify com Times.Never é uma escolha melhor ... Concordo com alex que esta solução funciona, mas é definitivamente obscura.
Beep beep
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.