Verwenden von Moq zum Verspotten einer asynchronen Methode für einen Komponententest

Ich teste eine Methode für einen Dienst, der ein Web erstelltAPI Anruf. Mit einem normalenHttpClient Funktioniert problemlos für Komponententests, wenn ich den Webdienst (in einem anderen Projekt in der Lösung) auch lokal ausführe.

Wenn ich meine Änderungen einchecke, hat der Build-Server jedoch keinen Zugriff auf den Webdienst, sodass die Tests fehlschlagen.

Ich habe einen Weg gefunden, um dies für meine Unit-Tests zu umgehen, indem ich eineIHttpClient Benutzeroberfläche und Implementierung einer Version, 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 ein OK zurückgebenHttpStatusResult für diesen speziellen Test. Für einen anderen ä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 der asynchronen Programmierung, bei Delegierten und in Moq selbst und habe SO und Google eine Weile lang gesucht, um neue Dinge zu lernen, aber ich scheine immer noch nicht über dieses Problem hinwegzukommen.

Hier ist die Methode, die ich testen möchte:

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 deine Hilfe.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage