9
votes

Test d'unité pour le code asynchrone

J'ai reçu du code, qui utilise httpwebrequest .begestreponse () méthode et il est asynchrone. En outre, j'utilise le projet d'application de test de l'unité de Microsoft pour la demande de test.

Le problème est que le cadre de test n'attend pas la fin du code asynchrone à la fin du code d'exécution, je ne peux donc pas vérifier son résultat.

Comment dois-je tester le code asynchrone à l'aide d'un projet d'app test d'unité? Je n'utilise pas ASYNC / Await des modificateurs.


5 commentaires

Avez-vous pensé d'utiliser des simulacres pour la classe / méthodes Web?


Test de l'unité Autre Code SPÉCIFIQUE SIGNELLE Comme Httpwebrequest Class peut ne pas être bon. Parce que vous êtes juste unitaire testant votre module, pensez que si l'autre module retourne une valeur valide, une valeur non valide et une exp en expectoration. Il serait donc préférable que vous puissiez vous moquer du httpwebrequest et de tester votre logique.


Oui, j'utilise des simulacres: le serveur retourne Json pour moi, alors j'utilise des moqueurs Jsons pour le transmettre au module d'analyse. Mais maintenant, je dois ajouter de la mise en cache des requêtes à ma mise en œuvre de l'API, alors j'ai besoin de vérifier comment cela fonctionne sans déboguer à chaque fois.


Si votre test nécessite des ressources externes telles que des bases de données ou une connexion réseau, il n'est plus un test d'unité mais déjà un test d'intégration. Un cadre de test unitaire peut ne pas être le bon outil.


Vous devriez se moquer de vos objets. Vérifiez Stackoverflow.com/Questtions/2113697/...


3 Réponses :


5
votes

Réponse de mise à jour

La réponse originale était assez ancienne, avant async et attendre était répandu. Je recommanderais maintenant de les utiliser, en écrivant quelque chose comme: xxx

Il y a un bon article qui couvre cela en profondeur ASYNC Programmation: Test de l'unité Code asynchrone

Ancienne réponse

I aurait tendance à quelque chose de simple comme en utilisant une boucle de vote et de vérifier un drapeau qui serait défini dans le code ASYNC ou vous pouvez utiliser des événements de réinitialisation. Un exemple simple utilisant des threads: xxx

Vous devez penser à des exceptions et utiliser un essai / enfin et signaler les erreurs à le faire correctement, mais vous obtenez l'idée. Cependant, cette méthode pourrait ne pas convenir si vous faites beaucoup de choses asynchrones encore et encore, à moins que vous fantaissiez de pousser cela dans une méthode réutilisable.


4 commentaires

Bonne idée, ça marche génial pour moi! Merci :) P.s. Vous avez eu une erreur dans tandis que (asyncdone) il devrait nier la condition: tandis que (! asyncdone)


Pourquoi sonder quand il y a beaucoup de meilleures façons d'attendre que le code asynchrone ait terminé. ( manuel / autoréfortezevent , moniteur , etc.) ou mieux si vous allez utiliser quelque chose comme ce qui précède, pourquoi pas seulement thread.join () < / code>?


Pour développer le commentaire de @iridium: ou utiliser async / attendre ... (bien réellement la tâche. Await ()))


@Iridium: tout bon suggère, mis à jour ma réponse pour en refléter l'un d'entre eux.



2
votes

Vous pouvez également utiliser un motif async / attendre (à l'aide du wrapper code> httpwebrequest code> à partir du Microsoft.bcl.Async Paquet Nuget ). Cela gérera également de manière proprement une exception sur laquelle se produisait dans votre fil de fond.

Par exemple: P>

[TestMethod]
public void RunTest()
{
    bool asyncDone = false;

    // this is a dummy async task - replace it with any awaitable Task<T>
    var task = Task.Factory.StartNew(() => 
    {
        // throw here to simulate bad code
        // throw new Exception();

        // Do some stuff
        asyncDone = true;
    });

    // Use Task.Wait to pause the test thread while the background code runs.
    // Any exceptions in the task will be rethrown from here.
    task.Wait();

    // check our result was as expected
    Assert.AreEqual(true, asyncDone);
}


0 commentaires

0
votes

Il est tard mais je suppose que cela serait beaucoup plus lisible et authentique xxx


0 commentaires