¿Cómo verificar que el método NO fue llamado en Moq?

466

¿Cómo verifico que el método NO fue llamado en Moq ?

¿Tiene algo como AssertWasNotCalled?

ACTUALIZACIÓN: a partir de la versión 3.0, se puede utilizar una nueva sintaxis:

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

Respuestas:

155

ACTUALIZACIÓN : desde la versión 3, verifique la actualización de la pregunta anterior o la respuesta de Dann a continuación.

O bien, haga que su simulación sea estricta para que falle si llama a un método para el que no tiene expectativas

new Mock<IMoq>(MockBehavior.Strict)

O, si quieres que tu simulacro se suelte, usa .Throws (Excepción)

var m = new Mock<IMoq>(MockBehavior.Loose);
m.Expect(a => a.moo()).Throws(new Exception("Shouldn't be called."));
Dan Fish
fuente
99
... o Callback () para establecer un indicador que se pueda afirmar
alex
2
También con la opción # 2, no puede tener un VerifyAll en un método general de desmontaje; fallará al decir que no se cumplió la expectativa; cuando la prueba debería pasar idealmente.
Gishu
51
Esto no es realmente un "verificar no llamado", ya que podría quedar atrapado dentro del método y seguiría funcionando, ¡proporcionando un falso positivo!
Dan
44
La expectativa ahora está en desuso
Tomasz Sikora
55
Esta podría haber sido la mejor manera posible en 2009, pero ciertamente no ahora. lo siento
Fabio Milheiro
537

Ejecute una verificación después de la prueba que tiene una Times.Neverenumeración establecida. p.ej

_mock.Object.DoSomething()
_mock.Verify(service => service.ShouldntBeCalled(),Times.Never());
Dan
fuente
44
Lo importante aquí es que la llamada Verificar (acción, Nunca) es posterior a la invocación al simulacro. Pensé que estaba configurando la verificación para llamar a VerifyAll () más tarde (lo que no funciona)
piers7
Simple y efectivo. Gracias.
Ian Grainger el
45

Robado de: la respuesta de John Foster a la pregunta, "Necesito ayuda para entender mejor a Moq"

Una de las cosas que es posible que desee probar es que no se llama al método de pago cuando una persona mayor de 65 años pasa al 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());
}
Chris Marisic
fuente
10

Esto no funciona en versiones recientes de Moq (desde al menos 3.1), debe especificarse en el Verifymétodo como se menciona en la respuesta.

En realidad, es mejor especificar .AtMost(0)después de la declaración de Devoluciones.

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

Aunque los "tiros" también funcionan, AtMost(0)es más expresivo en mi humilde opinión.

miha
fuente
-5

Utilice .AtMostOnce ();

Después de la prueba real, llame al método nuevamente. Si arroja una excepción, se llamó.

Aaron Digulla
fuente
1
¿No es un poco demasiado oscuro, para afirmar que la excepción fue lanzada por el marco burlón?
alex
¿Por qué? Simplemente verifique el tipo de excepción. Si es uno arrojó mi Moq, estás a salvo.
Aaron Digulla
8
Usar Verify with Times. Nunca es una mejor opción ... Estoy de acuerdo con alex en que esta solución funciona, pero definitivamente es oscura.
Beep beep