2009-02-11 16 views
370

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

¿Tiene algo así como AssertWasNotCalled?

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

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

Creo que deberías publicar tu respuesta a continuación en lugar de publicarla en tu pregunta. De lo contrario, es un poco raro;) – ForceMagic

Respuesta

133

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

O, hacer que su maqueta estricta por lo que se producirá un error si se llama a un método para el que no tiene una espera

new Mock<IMoq>(MockBehavior.Strict) 

O bien, si desea que su maqueta a estar suelto, utilice los .Throws (Excepción)

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

... o Devolución de llamada() para establecer un indicador que se puede afirmar. – alex

+2

También con la opción n. ° 2, no puede tener un VerifyAll en un método de Desarmado general; fallará diciendo que no se cumplió la expectativa; cuando la prueba idealmente debería pasar. – Gishu

+38

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! – Dann

-4

Uso .AtMostOnce();

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

+1

No es demasiado oscuro para afirmar que la excepción fue lanzada por el marco de burla? – alex

+0

¿Por qué? Solo verifica el tipo de la excepción. Si es uno arrojó mi Moq, estás a salvo. –

+6

Usar Verificar con Times. Nunca es una mejor opción ... Estoy de acuerdo con Alex en que esta solución funciona, pero definitivamente es oscura. –

10

Esto no funciona en versiones recientes de Moq (desde al menos 3,1), debe ser especificado en el método Verify 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 el "tiros" también funciona, en mi humilde opinión AtMost(0) es más expresivo.

+2

no puedo encontrar esto en Moq v3.1 – Gishu

+0

no funcionará para los métodos que no tienen un valor de retorno – joshperry

22

robados de: John Foster's answer to the question, "Need help to understand Moq better"

Una de las cosas que puede que desee probar es que el método de pago no se consiga llamar cuando una persona mayor de 65 años se pasa en el 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()); 
} 
423

Ejecute una verificación después de la prueba que tiene un conjunto de enumeración Times.Never. p.ej.

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

Lo que es crítico aquí es que la llamada de verificación (acción, nunca) es * después * de la invocación al simulacro . Pensé que estaba configurando la verificación para llamar a VerifyAll() más tarde (que * no * funciona) – piers7

Cuestiones relacionadas