2009-04-15 10 views
2

Ce test échoue lorsqu'il est exécuté avec le coureur de la console NUnit. Il fonctionne si je viens de lancer ce test avec TestDriven.NET, mais pas si je cours toute la suite avec TestDriven.NET:C#/.NET: Test de BackgroundWorker avec NUnit

[Test] 
public void BackgroundWorkerFiresRunWorkerCompleted() 
{ 
    var runner = new BackgroundWorker(); 
    ManualResetEvent done = new ManualResetEvent(false); 
    runner.RunWorkerCompleted += delegate { done.Set(); }; 

    runner.RunWorkerAsync(); 

    bool res = done.WaitOne(TimeSpan.FromSeconds(10)); 
    // This assert fails: 
    Assert.IsTrue(res, "RunWorkerCompleted was not executed within 10 seconds"); 
} 

Je soupçonne que le problème a quelque chose à voir avec ne pas avoir une boucle de message, mais Je ne suis pas sûr.

Quelle est la configuration requise pour utiliser BackgroundWorker?

Y a-t-il une solution de contournement pour que le test fonctionne?

Répondre

7

Je ne pense pas que cela ait à voir avec la pompe à messages, puisque les tests fonctionnent généralement de manière bloquante. Mais il se peut que l'événement soit invoqué sur le thread "UI", qui utilise un message Windows qui n'est pas géré.

Ainsi, si le problème a été la pompe de messages ou les fenêtres des messages ne sont pas traitées, vous pouvez essayer comme ceci pour remplacer votre ligne bool res = done.WaitOne(TimeSpan.FromSeconds(10)); actuelle:

DateTime end = DateTime.Now.AddSeconds(10); 
bool res = false; 
while ((!res) && (DateTime.Now<end)) { 
    Application.DoEvents(); 
    res = done.WaitOne(0): 
} 
+0

Cela fonctionne. Merci! –

+0

Nous avons trouvé que DoEvents() n'est requis que lorsque le test (ou un test précédent dans le même test) instancie un formulaire ou un contrôle Windows. Pourquoi? –

+0

Parce que pour n'importe quel contrôle WinForms, les messages de fenêtre doivent être passés à travers la pompe de message, ce qui n'arrive pas si vous n'appelez pas 'DoEvents()'. – Lucero

0

Un gestionnaire d'événements BGW DoWork vous manque?

+0

La classe réelle que je veux tester les sous-classes BackgroundWorker et redéfinit OnDoWork(). Mais cela ne fait aucune différence si j'ajoute un gestionnaire d'événements DoWork. Le gestionnaire d'événements RunWorkerCompleted n'est toujours pas exécuté. –

-2

Il suffit d'ajouter un sommeil avant:

Assert.IsTrue(res, "RunWorkerCompleted was not executed within 10 seconds");

Quelque chose comme ceci:

System.Threading.Thread.Sleep(10000);

+3

Mais cela rendrait le test toujours prendre au moins 10 secondes, alors qu'il devrait normalement se terminer en millisecondes. –

Questions connexes