J'écris un test qui s'attend à recevoir un événement d'un objet qu'il appelle. Plus précisément, j'appelle à un objet qui se connecte à une machine AIX via SSH (en utilisant le projet open source Granados), puis déconnecte, et je veux m'assurer de recevoir l'événement OnConnectionClosed qui est levé pendant la déconnexion. Cela semble assez simple, et j'ai écrit de nombreux tests comme celui-ci dans le passé, mais cette fois, il se produit un comportement étrange qui, je crois, est lié au threading.Comment écrire un test d'unité MSTest à l'écoute d'un événement à déclencher à partir d'un autre thread?
Fondamentalement, l'objet que j'appelle soulève l'événement 'OnConnectionClosed' sur un thread différent de celui que je l'appelle. Ce que je vois, c'est que quand j'exécute le test en sélectionnant 'Test de débogage', ça passe, mais si je choisis 'Exécuter Test', ça échoue (même s'il n'y a pas de points d'arrêt pendant le débogage). J'ai fait un peu de Googling et trouvé this post qui semble indiquer que par défaut l'hôte MSTest s'exécute en mode Single Thread mais qu'un changement de configuration peut le faire fonctionner en mode Multi Thread. Cela sonnait comme si cela réglerait logiquement mon problème, mais bien sûr, ce n'était pas le cas. Certains autres messages que j'ai rencontrés me font penser que MSTest ne surveille tout simplement pas les threads d'arrière-plan (donc les événements qu'ils soulèvent ne sont pas 'entendus'). Cela aurait également du sens, et comme il semble fonctionner en mode débogage, et il semble que le correctif ci-dessus devrait logiquement résoudre ce problème, alors je suis confus quant à savoir pourquoi cela ne fonctionne pas. Il est possible que je ne traite pas correctement les threads, bien que je m'attendrais à ce que ce soit encore un problème en mode debug si c'était le cas.
Est-ce que quelqu'un d'autre a essayé de tester quelque chose d'une manière similaire? Si oui, avez-vous rencontré des problèmes similaires? Et si oui, comment les avez-vous résolus?
J'ai collé le code de test unitaire pertinent ci-dessous (j'ai supprimé les informations de connexion pour des raisons de sécurité).
[TestClass]
public class SSHReaderTests
{
private bool received = false;
private delegate bool SimpleFunc();
[TestInitialize]
public void MyTestInitialize()
{
received = false;
}
[TestMethod]
public void Should_raise_OnReaderConnectionClosed_event_after_successful_connection_is_disconnected()
{
IReader reader = new SSHReader();
reader.OnReaderConnectionClosed += delegate
{
received = true;
};
reader.Connect("*****", "*****", "*****");
//Assert.IsTrue(reader.IsConnected);
reader.Disconnect();
//Assert.IsFalse(reader.IsConnected);
Assert.IsTrue(WaitUntilTrue(delegate {
return received; }, 30000, 1000));
}
private static bool WaitUntilTrue(SimpleFunc func, int timeoutInMillis, int timeBetweenChecksInMillis)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
while(stopwatch.ElapsedMilliseconds < timeoutInMillis)
{
if (func())
return true;
Thread.Sleep(timeBetweenChecksInMillis);
}
return false;
}
}