tests unitaires du code asynchrone n'est pas la chose la plus simple du monde, comme je l'ai appris lors de l'écriture des tests unitaires pour ma bibliothèque Nito.Async. :)
D'abord, vous voulez définir ce que vous voulez réellement tester. Voulez-vous simplement tester si l'action asynchrone est effectuée ou voulez-vous vous assurer que vos tâches/tâches BGW synchronisent correctement leurs rapports d'avancement de l'interface utilisateur?
Le test de l'action est assez simple: attendez que l'action soit terminée et vérifiez les postconditions. (Cependant, sachez que le BGW RunWorkerCompleted
sera déclenché sur un thread ThreadPool
sauf si vous lui donnez un contexte de synchronisation comme dans l'exemple ci-dessous).
La vérification d'une synchronisation correcte (par exemple, que chaque partie du code s'exécute sur le bon thread) est plus complexe.
Pour chaque test, vous devez établir un contexte de synchronisation. Cela se moquera du contexte de synchronisation de l'interface utilisateur. Ma bibliothèque Nito.Async peut aider avec cela; il a un ActionThread
qui est un thread séparé qui contient un contexte de synchronisation approprié pour posséder des composants EAP (par exemple, BGW) et des tâches de planification (par exemple, TaskScheduler.FromCurrentSynchronizationContext
).
Il peut être utilisé comme celui-ci (en utilisant un exemple MSTest):
[TestMethod]
public void Test()
{
using (ActionThread thread = new ActionThread())
{
thread.Start();
// Anything passed to Do is executed in that ActionThread.
thread.Do(() =>
{
// Create BGW or call TaskScheduler.FromCurrentSynchronizationContext.
});
// The thread is gracefully exited at the end of the using block.
}
}
je trouve Thread.CurrentThread.ManagedThreadId
et Thread.CurrentThread.IsThreadPoolThread
être les moyens les plus faciles à vérifier pour la synchronisation appropriée. Si votre code de test est exécuté à partir de ActionThread.Do
, il doit synchroniser ses mises à jour de progression (et la notification d'achèvement) à ActionThread
.
Un grand nombre de tests unitaires Nito.Async utilisent ActionThread
de cette manière, vous pouvez donc y rechercher divers exemples.
Pouvez-vous être un peu plus précis? Peut-être poster du code afin que nous puissions voir comment votre code est structuré et répondre en conséquence ... – BFree
@BFree. Oui, la question est délicate et peut-être trop vague, mais tout le code que j'ai maintenant ne se prête pas à un court message ou à une réponse rapide. Si la question était de commencer à utiliser des simulacres, par exemple, peut-être que quelqu'un suggèrerait Rhino avec le wiki et peut-être un bon post de blog sur le démarrage avec quelques conseils de leur propre expérience. Cheers – Berryl