2014-01-21 17 views
161

ich eine Schnittstelle haben, dieSetup-Asynchron-Task-Rückruf in Moq Rahmen

Task DoSomethingAsync(); 

Ich verwende MoqFramework für meine Tests erklärt:

[TestMethod()] 
public async Task MyAsyncTest() 
{ 
    Mock<ISomeInterface> mock = new Mock<ISomeInterface>(); 
    mock.Setup(arg => arg.DoSomethingAsync()).Callback(() => { <my code here> }); 
    ... 
} 

Dann in meinem Test ausführen ich den Code der ruft await DoSomethingAsync() auf. Und der Test schlägt gerade in dieser Zeile fehl. Was mache ich falsch?

+4

Wenn Sie die Testfehler auf dieser Linie sagen, welche Fehler hat es produzieren? – AlSki

Antwort

353

Ihre Methode hat keine Rückrufe, daher gibt es keinen Grund, .CallBack() zu verwenden. Sie können einfach zurückgeben eine Aufgabe mit den gewünschten Werten .Returns() und Task.FromResult, z.B .:

MyType someValue=...; 
mock.Setup(arg=>arg.DoSomethingAsync())   
    .Returns(Task.FromResult(someValue)); 

-Update 2014-06-22

Moq 4.2 hat zwei neue Erweiterungsmethoden mit diesem zu helfen.

mock.Setup(arg=>arg.DoSomethingAsync()) 
    .ReturnsAsync(someValue); 

mock.Setup(arg=>arg.DoSomethingAsync())   
    .ThrowsAsync(new InvalidOperationException()); 

-Update 2016-05-05

Wie Seth Blumen erwähnt im other answer ist ReturnsAsync nur für Methoden zur Verfügung, die eine Task<T> zurückzukehren. Für Methoden, die nur eine Aufgabe zurückgeben, kannverwendet werden.

Was .Returns(Task.CompletedTask); in .NET 4.6 ist dies in this answer, vereinfacht dargestellt, zB:

mock.Setup(arg=>arg.DoSomethingAsync())   
    .Returns(Task.CompletedTask); 
+0

Es löste das Problem. Vielen Dank! – Waldemar

+6

.Returns (Task.CompletedTask); das war meine Antwort –

+3

ReturnsAsync funktioniert großartig. – Sully

28

ähnliche Ausgabe

Ich habe eine Schnittstelle, die in etwa so aussah:

Task DoSomething(int arg); 

Symptome

Mein Komponententest ist fehlgeschlagen, wenn mein Dienst im Test awaited der Anruf an DoSomething ist.

Fix

Im Gegensatz zu der akzeptierten Antwort, Sie sind nicht in der Lage .ReturnsAsync() auf Setup() diese Methode in diesem Szenario zu nennen, weil die Methode die nicht-generic Task, anstatt Task<T> zurückzugibt.

Sie können jedoch weiterhin .Returns(Task.FromResult(default(object))) im Setup verwenden, damit der Test bestanden wird.

+1

Nur ein Gedanke zu diesem, wenn Sie eine nicht-generische Aufgabe (nicht. NET 4.6) zurückgeben, würde ich in Betracht ziehen, Task.Delay (1) als eine einfache Möglichkeit, eine Aufgabe zurückgeben. Sie können Arbeit auch nachahmen, indem Sie das Zeitargument erhöhen. – stevethethread

13

Sie müssen nur .Returns(Task.FromResult(0)); nach dem Rückruf hinzufügen.

Beispiel:

mock.Setup(arg => arg.DoSomethingAsync()) 
    .Callback(() => { <my code here> }) 
    .Returns(Task.FromResult(0));