À l'aide de Moq pour se moquer d'une méthode asynchrone pour un test unitaire
Je suis en train de tester une méthode de service Web API
appel. À l'aide d'un normal HttpClient
fonctionne très bien pour les tests unitaires si je dirige également le service web (situé dans un autre projet dans la solution) localement.
Cependant lorsque je vérifie dans mes modifications du serveur de build n'ont pas accès au service web afin que les tests échouent.
J'ai imaginé un moyen de contourner cela pour mes tests d'unité par la création d'un IHttpClient
de l'interface et de l'implémentation d'une version que j'utilise dans mon application. Pour les tests unitaires, je fais un moqué de la version complète avec un moqué asynchrone de la méthode post. Voici où j'ai couru dans des problèmes. Je veux revenir un OK HttpStatusResult
pour ce test particulier. Pour un autre test similaire je serai de retour un mauvais résultat.
Le test fonctionne, mais ne sera jamais complète. Il se bloque à l'attendent. Je suis nouveau dans la programmation asynchrone, les délégués, et Moq lui-même, et j'ai cherché SI et google pour un tout en apprenant de nouvelles choses mais je ne peux pas sembler obtenir passé ce problème.
Voici la méthode que je suis en train 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 mon test de l'unité de la méthode:
[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.");
}
Ce que je fais mal?
Merci pour votre aide.
Vous devez vous connecter pour publier un commentaire.
Vous êtes à la création d'une tâche, mais jamais de départ, c'est de ne jamais se terminer. Cependant, ne pas commencer la tâche au lieu de cela, le changement à l'aide de
Tâche.FromResult<TResult>
qui vont vous donner une tâche qui a déjà effectué:Noter que vous ne serez pas tester la réelle asynchronisme de cette façon - si vous voulez le faire, vous avez besoin de faire un peu plus de travail pour créer un
Task<T>
que vous pouvez contrôler dans une plus fine de la manière... mais c'est quelque chose pour un autre jour.Vous pourriez aussi envisager d'utiliser un faux pour
IHttpClient
plutôt que de se moquer de tout - cela dépend vraiment de combien de fois vous en avez besoin.ReturnsAysnc
, qui fait exactement cela.await
) à passer des examens.