Ich teste eine Methode für einen Dienst, der einen Webanruf API
tätigt. Die Verwendung eines Normalen HttpClient
funktioniert gut für Unit-Tests, wenn ich den Webdienst (der sich in einem anderen Projekt in der Lösung befindet) auch lokal ausführe.
Wenn ich jedoch meine Änderungen einchecke, hat der Build-Server keinen Zugriff auf den Webdienst, sodass die Tests fehlschlagen.
Ich habe einen Weg gefunden, dies für meine Komponententests zu umgehen, indem IHttpClient
ich eine Schnittstelle erstellt und eine Version implementiert habe, die ich in meiner Anwendung verwende. Für Unit-Tests erstelle ich eine verspottete Version mit einer verspotteten asynchronen Post-Methode. Hier bin ich auf Probleme gestoßen. Ich möchte HttpStatusResult
für diesen speziellen Test ein OK zurückgeben . Für einen weiteren ähnlichen Test werde ich ein schlechtes Ergebnis zurückgeben.
Der Test wird ausgeführt, aber niemals abgeschlossen. Es hängt am Warten. Ich bin neu in asynchroner Programmierung, Delegierten und Moq selbst und habe eine Weile nach SO und Google gesucht, um neue Dinge zu lernen, aber ich kann dieses Problem immer noch nicht überwinden.
Hier ist die Methode, die ich zu testen versuche:
public async Task<bool> QueueNotificationAsync(IHttpClient client, Email email)
{
// do stuff
try
{
// The test hangs here, never returning
HttpResponseMessage response = await client.PostAsync(uri, content);
// more logic here
}
// more stuff
}
Hier ist meine Unit-Test-Methode:
[TestMethod]
public async Task QueueNotificationAsync_Completes_With_ValidEmail()
{
Email email = new Email()
{
FromAddress = "[email protected]",
ToAddress = "[email protected]",
CCAddress = "[email protected]",
BCCAddress = "[email protected]",
Subject = "Hello",
Body = "Hello World."
};
var mockClient = new Mock<IHttpClient>();
mockClient.Setup(c => c.PostAsync(
It.IsAny<Uri>(),
It.IsAny<HttpContent>()
)).Returns(() => new Task<HttpResponseMessage>(() => new HttpResponseMessage(System.Net.HttpStatusCode.OK)));
bool result = await _notificationRequestService.QueueNotificationAsync(mockClient.Object, email);
Assert.IsTrue(result, "Queue failed.");
}
Was mache ich falsch?
Danke für Ihre Hilfe.
quelle
ReturnsAysnc
, die genau dies tut.Empfehlen Sie die Antwort von @Stuart Grassie oben.
quelle
Mit
Mock.Of<...>(...)
for-async
Methode können Sie verwendenTask.FromResult(...)
:quelle