web-dev-qa-db-fra.com

Comment se moquer d'un résultat de tâche <>?

J'installe des tests unitaires et j'utilise Rhino Mocks pour remplir l'objet testé. Une des choses dont on se moque est un Task<HttpResponseMessage>, car la logique testée inclut un appel à un HttpClient pour obtenir une réponse asynchrone.

J'ai donc commencé à configurer les simulateurs comme ceci:

var httpClient = MockRepository.GenerateMock<HttpClient>();
var taskFunc = MockRepository.GenerateMock<Func<HttpResponseMessage>>();
var responseTask = MockRepository.GenerateMock<Task<HttpResponseMessage>>(taskFunc);
var response = MockRepository.GenerateMock<HttpResponseMessage>();

httpClient.Stub(c => c.PostAsJsonAsync<IEnumerable<LogMessage>>(Arg<string>.Is.Anything, Arg<IEnumerable<LogMessage>>.Is.Anything)).Return(responseTask);
responseTask.Stub(t => t.Result).Return(response);
response.Stub(r => r.IsSuccessStatusCode).Return(true);

(L'étape "act" du test consistera à instancier l'objet testé, à l'alimenter httpClient et à exécuter une méthode dessus. "Assert" vérifiera via les simulations que les appels de méthode attendus ont été effectués sur eux.)

En traversant cela dans un débogueur, il y a un blocage indéfini sur cette ligne:

responseTask.Stub(t => t.Result).Return(response);

Je n'ai pas beaucoup d'expérience avec Rhino Mocks ou avec C # async, donc je peux ignorer quelque chose d'évident. Le but, bien sûr, est que tout appel au .Result la propriété renverrait la maquette response. Mais il semble que ma tentative elle-même invoque peut-être .Result que je m'attendrais à attendre indéfiniment car ce n'est qu'une maquette, peut-être?

Quelle est la bonne façon d'organiser cela? Essentiellement, je dois fournir à mon objet un HttpClient simulé et affirmer qu'une méthode a été appelée avec un argument spécifique.

38
David

Le plus simple est de renvoyer une tâche terminée avec le résultat attendu:

var responseTask = Task.FromResult(response);

J'imagine que la raison pour laquelle cela se bloque est que la tâche simulée n'est jamais démarrée et que la fonction donnée n'est donc pas exécutée. Vous pouvez le démarrer dans votre test:

var responseTask = MockRepository.GenerateMock<Task<HttpResponseMessage>>(taskFunc);
responseTask.Start();

Cependant, il n'y a aucune raison de se moquer des tâches, car vous pouvez facilement créer directement des tâches terminées/échouées/annulées.

59
Lee