it-swarm.com.de

Wie kann ich Moq anweisen, eine Aufgabe zurückzugeben?

Ich habe eine Schnittstelle, die deklariert

Task DoSomethingAsync();

Ich benutze MoqFramework für meine Tests:

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

Dann führe ich in meinem Test den Code aus, der await DoSomethingAsync() aufruft. Und der Test schlägt in dieser Zeile einfach fehl. Was mache ich falsch?

272
Waldemar

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

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

Update 22.06.2014

Moq 4.2 hat zwei neue Erweiterungsmethoden, um dies zu unterstützen.

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

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

Update 05.05.2016

Wie Seth Flowers in andere Antwort erwähnt, ist ReturnsAsync nur für Methoden verfügbar, die einen Task<T> Zurückgeben. Für Methoden, die nur eine Aufgabe zurückgeben,

.Returns(Task.FromResult(default(object)))

kann verwendet werden.

Wie in diese Antwort gezeigt, wird dies in .NET 4.6 zu .Returns(Task.CompletedTask); vereinfacht, z.

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

Ähnliches Problem

Ich habe eine Oberfläche, die ungefähr so ​​aussah:

Task DoSomething(int arg);

Symptome

Mein Komponententest ist fehlgeschlagen, als mein zu testender Dienst awaited den Aufruf von DoSomething ausführte.

Fix

Anders als bei der akzeptierten Antwort können Sie in diesem Szenario .ReturnsAsync() für Ihre Setup() dieser Methode nicht aufrufen, da die Methode nicht generisch Task zurückgibt, sondern Task<T>.

Sie können jedoch weiterhin .Returns(Task.FromResult(default(object))) für das Setup verwenden, damit der Test bestanden werden kann.

37
Seth Flowers

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));
24
Diego Torres

Jetzt können Sie auch das Talentsoft.Moq.SetupAsync-Paket https://github.com/TalentSoft/Moq.SetupAsync verwenden.

Was auf der Basis der hier gefundenen Antworten und hier noch nicht umgesetzten Ideen an Moq geht: https://github.com/moq/moq4/issues/384 , vereinfacht die Einrichtung von asynchronen Methoden erheblich

Einige Beispiele aus früheren Antworten mit der SetupAsync-Erweiterung:

mock.SetupAsync(arg=>arg.DoSomethingAsync());
mock.SetupAsync(arg=>arg.DoSomethingAsync()).Callback(() => { <my code here> });
mock.SetupAsync(arg=>arg.DoSomethingAsync()).Throws(new InvalidOperationException());
3
user9812476