2016-04-05 2 views
4

Ich versuche, Moq zu verwenden, um die Integration zwischen einem WebAPI-Controller und einer Redis-Datenbank mit dem StackExchange.Redis-Client zu testen, und kann nicht herausfinden, wie eine verifizierbare Erwartung für eine verspottete asynchrone Methode eingerichtet wird, die einen Callback oder einige enthält anderes Assertionsverhalten.Wie richte ich eine verifizierbare Erwartung für eine verspottete Async-Methode ein?

Normalerweise würde ich die folgende Syntax verwenden:

const string KEY = "some_key"; 
var db = new Mock<IDatabase>(); 
db.Setup(d => d.HashSetAsync(KEY, It.IsAny<HashEntry[]>(),It.IsAny<CommandFlags>())) 
    .Callback<RedisKey,HashEntry[],CommandFlags>((key, hash, flags) => { 
       hash.ShouldContain(entry => entry.Name == "customerid"); 
       hash.ShouldContain(entry => entry.Name == "quotenumber"); 
    }) 
    .Verifiable(); 

Aber das gibt mir:

‚Moq.Language.Flow.IReturnsThrows < StackExchange.Redis.IDatabase, System. Threading.Tasks.Task > 'enthält keine Definition für' Verifizierbar 'und es wurde keine Erweiterungsmethode' Verifizierbar 'gefunden, die ein erstes Argument des Typs' Moq.Language.Flow.IReturnsThrows 'akzeptiert (fehlt eine using-Direktive oder ein Bezugsnummer?)

Wenn ich db.HashSetAsync zu db.HashSet in der Setup Aufruf ändern, funktioniert es wie erwartet. Es scheint, dass die Einstellung eines Callbacks für eine reguläre Methode ICallbackResult zurückgibt, aber das Festlegen eines Callbacks für einen asynchronen Methodenaufruf gibt IReturnsThrows zurück - und ich bin mir nicht sicher, wie Sie einen davon als überprüfbar markieren. Irgendwelche Ideen?

+0

Sie scheinen eine Rückkehr zu fehlen von Ihrem Setup für den Rückruf. welchen Typ gibt 'HashSetAsync' zurück? – Nkosi

+1

Warum verwendest du' ReturnsAsync' nicht? In Versionen, die es nicht haben, können Sie '.Returns (Task.FromResult (someValue)) verwenden;' –

+0

@PanagiotisKanavos bisher bin ich nicht auf 'ReturnsAsync' gestoßen. Wo suche ich danach? sieht interessant aus. – Nkosi

Antwort

5

Für Asynchron-Methoden, die Sie benötigen ein ausgefülltes Task aus dem Setup zurückzukehren, bevor Sie einen Rückruf

einen Blick mit hier:

Using Moq to mock an asynchronous method for a unit test

Sie erstellen eine Aufgabe, aber nie starten es ist also nie abgeschlossen. Jedoch nicht nur die Aufgabe starten - stattdessen zu ändern Task.FromResult<TResult> mit dem Sie geben eine Aufgabe, die bereits abgeschlossen hat:

das funktioniert

const string KEY = "some_key"; 
var db = new Mock<IDatabase>(); 
db.Setup(d => d.HashSetAsync(KEY, It.IsAny<HashEntry[]>(), It.IsAny<CommandFlags>())) 
    .Returns(Task.FromResult<object>(null)) 
    .Callback<RedisKey, HashEntry[], CommandFlags>((key, hash, flags) => { 
     hash.ShouldContain(entry => entry.Name == "customerid"); 
     hash.ShouldContain(entry => entry.Name == "quotenumber"); 
    }) 
    .Verifiable(); 
Verwandte Themen