2010-06-22 27 views
14

Obtengo un objeto Moq para devolver valores diferentes en llamadas sucesivas a un método. Esto se hace mediante este método de extensión:Devolver resultados diferentes o lanzar excepciones de llamadas sucesivas a Moq Mock

public static void ReturnsInOrder<T, TResult>(this ISetup<T, TResult> setup, params TResult[] results) where T : class 
{ 
    setup.Returns(new Queue<TResult>(results).Dequeue); 
} 

Ahora quiero que una de las llamadas genere una excepción mientras que otras devuelven algo. ¿Alguien ha hecho esto antes?

si hago esto

mock.Setup(m => m.SomeMethod()) 
    .Throws(new Exception()); 
mock.Setup(m => m.SomeMethod()) 
    .Returns("ok"); 

entonces la primera configuración se sobrescribe y sólo la segunda configuración persiste.

Respuesta

9

Utilicé el encadenamiento de devolución de llamada mientras desarrollé el proxy de reintentos.

var src = new Mock<ITest>(); 
src.Setup(s => s.RaiseError()).Callback(() => 
src.Setup(s => s.RaiseError())).Throws<Exception>(); 

const int retryCount = 1; 
var proxy = RetryProxy.MakeFor(src.Object, retryCount); 

proxy.RaiseError(); 
src.Verify(s => s.RaiseError(), Times.Exactly(retryCount+1)); 
+0

Esta solución (más bien complicado) ya no es necesario ya que Moq tiene soporte para el método SetupSequence. Vea mi respuesta a continuación para un ejemplo. – nashwan

10

Hoy en día Moq (versión 4+) soporta este a través de su método SetupSequence. Ver this post para una introducción.

+1

Pero en el lanzamiento oficial no permite devolver un valor del método simulado después de lanzar una excepción (aún es posible hacerlo en orden inverso) - https://code.google.com/p/moq/issues/detail? id = 319 – Marek

0

Utilice SetupSequence(...) en el objeto de simulacro.

Por ejemplo, la siguiente emitir la excepción en la primera llamada y volver someResponse en la segunda llamada:

myService.SetupSequence(s => s.PlaceOrder()) 
    .Throws(new Exception()) 
    .Returns(someResponse); 
+0

Lanza devoluciones vacías por lo que esta orden no está permitida (utilizando Moq versión 4.0) –

+0

¿Estás seguro? Porque estoy usando esta línea de código real y funciona bien para mí. Estoy usando Moq versión 4.0.30319. ¿Estás seguro de que realmente se está llamando a tu "Orden de posición()" (o método equivalente)? – nashwan

+0

Estoy usando Moq.WithoutCastle-Version 4.0.10827.2 y el código no se compilará. Quizás es una limitación de Moq.WithoutCastle. –

Cuestiones relacionadas