Je teste une méthode pour un service qui effectue un API
appel Web . L'utilisation d'un normal HttpClient
fonctionne bien pour les tests unitaires si j'exécute également le service Web (situé dans un autre projet de la solution) localement.
Cependant, lorsque j'enregistre mes modifications, le serveur de compilation n'aura pas accès au service Web, donc les tests échoueront.
J'ai imaginé un moyen de contourner ce problème pour mes tests unitaires en créant une IHttpClient
interface et en implémentant une version que j'utilise dans mon application. Pour les tests unitaires, je crée une version simulée complète avec une méthode de publication asynchrone simulée. Voici où j'ai rencontré des problèmes. Je veux retourner un OK HttpStatusResult
pour ce test particulier. Pour un autre test similaire, je retournerai un mauvais résultat.
Le test s'exécutera mais ne se terminera jamais. Il s'accroche à l'attente. Je suis nouveau dans la programmation asynchrone, les délégués et Moq lui-même et je cherche depuis un certain temps SO et Google pour apprendre de nouvelles choses, mais je n'arrive toujours pas à surmonter ce problème.
Voici la méthode que j'essaye de tester:
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
}
Voici ma méthode de test unitaire:
[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.");
}
Qu'est-ce que je fais mal?
Merci de votre aide.
la source
ReturnsAysnc
, qui fait exactement cela.Recommandez la réponse de @Stuart Grassie ci-dessus.
la source
Avec la méthode
Mock.Of<...>(...)
pourasync
, vous pouvez utiliserTask.FromResult(...)
:la source