2010-06-22 2 views
14

Ottengo un oggetto Moq per restituire valori diversi su chiamate successive a un metodo. Questo è il metodo di estensione:Restituzione di risultati diversi o generazione di eccezioni da chiamate successive 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); 
} 

Ora voglio che una delle chiamate generi un'eccezione mentre altri restituiscono qualcosa. Qualcuno l'ha già fatto prima?

se faccio questo

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

poi la la prima configurazione viene sovrascritto e solo la seconda impostazione persiste.

risposta

9

Ho utilizzato il concatenamento di callback durante lo sviluppo di un nuovo proxy.

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

Questa soluzione (piuttosto contorta) non è più necessario in quanto Moq ha il supporto per il metodo SetupSequence. Vedi la mia risposta qui sotto per un esempio. – nashwan

10

Oggi Moq (versione 4+) supporta questo attraverso il suo metodo SetupSequence. Vedi this post per un'introduzione.

+1

Ma nella versione ufficiale non consente di restituire un valore dal metodo simulato dopo aver generato un'eccezione (è comunque possibile farlo in ordine inverso) - https://code.google.com/p/moq/issues/detail? id = 319 – Marek

0

Utilizzare SetupSequence(...) sull'oggetto fittizio.

Ad esempio, il seguente sarà generare l'eccezione alla prima chiamata e tornare someResponse in seconda convocazione:

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

Restituisce i resi invalidi, quindi questo ordine non è consentito (utilizzando Moq versione 4.0) –

+0

Sei sicuro? Perché sto usando questa linea di codice e funziona perfettamente per me. Sto usando Moq versione 4.0.30319. Sei sicuro che il tuo "PlaceOrder()" (o metodo equivoco) sia effettivamente chiamato? – nashwan

+0

Sto usando Moq.WithoutCastle -Version 4.0.10827.2 e il codice non verrà compilato. Forse è una limitazione di Moq.WithoutCastle. –