2011-06-03 1 views
13

Après l'exécution des deux cas de test suivants, une exécution COM est imprimée sur la console. Qu'est-ce que je fais mal?Exceptions COM en sortie avec WPF

Si j'exécute un test seul ou si j'exécute les deux tests ensemble, l'exception est écrite une seule fois sur la console. Cela me fait penser qu'il y a une sorte de ressource par AppDomain que je ne nettoie pas.

J'ai essayé les tests avec NUnit et avec MSTest, avec le même comportement dans les deux environnements. (En fait, je ne suis pas sûr si vous utilisez les deux tests dans les résultats MSTest en une seule impression d'exception ou deux.)

Exception:

System.Runtime.InteropServices.InvalidComObjectException: COM object that has been separated from its underlying RCW cannot be used. 
at System.Windows.Input.TextServicesContext.StopTransitoryExtension() 
at System.Windows.Input.TextServicesContext.Uninitialize(Boolean appDomainShutdown) 
at System.Windows.Input.TextServicesContext.TextServicesContextShutDownListener.OnShutDown(Object target) 
at MS.Internal.ShutDownListener.HandleShutDown(Object sender, EventArgs e) 

Code d'essai:

using NUnit.Framework; 

namespace TaskdockSidebarTests.Client 
{ 
    [TestFixture, RequiresSTA] 
    public class ElementHostRCWError 
    { 
     [Test] 
     public void WinForms() 
     { 
      var form = new System.Windows.Forms.Form(); 
      var elementHost = new System.Windows.Forms.Integration.ElementHost(); 
      form.Controls.Add(elementHost); 

      // If the form is not shown, the exception is not printed. 
      form.Show(); 

      // These lines are optional. The exception is printed with or without 
      form.Close(); 
      form.Controls.Remove(elementHost); 
      elementHost.Dispose(); 
      form.Dispose(); 
     } 

     [Test] 
     public void WPF() 
     { 
      var window = new Window(); 

      // If the window is not shown, the exception is not printed. 
      window.Show(); 

      window.Close(); 
     } 
    } 
} 
+0

Peut-être http://social.msdn.microsoft.com/forums/en-US/vststest/thread/e53fdc45-23f3-4aee-aad9-f63769f2c638/ aide –

+0

Malheureusement, je ne peux pas utiliser MTA, comme WPF nécessite STA. Créer l'hôte de formulaire et d'élément dans SetUp ne semble pas non plus faire l'affaire. Argh. –

+0

Si je ne me trompe pas, cette exception ne provoque pas l'échec de l'échec, n'est-ce pas? J'ai rencontré la même exception lors de l'annulation de mes contrôles WPF, j'ai choisi de l'ignorer ..;) – Bubblewrap

Répondre

18

En regardant à nouveau mon propre code, la ligne suivante pourrait aider pour le test WPF, à la fin.

Dispatcher.CurrentDispatcher.InvokeShutdown(); 
+0

Sweeeeet! C'est ce qu'il a fait. Merci! Maintenant, je dois juste trouver comment l'intégrer dans mon architecture de test. –

+0

De façon décevante, une fois qu'un répartiteur est lié à un thread (c'est-à-dire, Dispatcher.CurrentDispatcher), aucun autre répartiteur ne peut être associé à ce thread. Et une fois qu'un répartiteur a été arrêté, il ne peut pas être redémarré. Donc, même si cela résout mon problème, je ne peux malheureusement pas simplement appeler InvokeShutdown() dans la méthode TearDown de ma classe de test de base. –

+0

Essayez de démarrer un nouveau thread STA dans chaque unittest, effectuez le test dans ce nouveau thread et attendez que ce thread se termine avec Thread.Join(). – Bubblewrap

1

Vous pouvez probablement 't testent les classes Window et Form. Les applications WinForms et les applications WPF ont une classe Application utilisée pour démarrer la plomberie sous-jacente (pompes à messages et autres). Je parie que c'est la clé pour éviter cette exception.

Vous ne le faites pas et vous ne pourrez peut-être pas le faire. Chaque recommandation pour les tests unitaires que j'ai jamais lus est que vous refactoriser de sorte que les classes Form et Window ne fassent rien que vous ayez besoin de tester (comme le modèle M-V-VM dans WPF). Pourrait avoir quelque chose à voir avec ne pas être en mesure de montrer l'interface utilisateur.

Il existe d'autres façons de tester une interface utilisateur. This answer traite de l'interface utilisateur de test unitaire.

+3

En fait, les tests fonctionnent bien - je finis avec beaucoup de merde dans mes fichiers journaux. En ce qui concerne le test de l'interface utilisateur par rapport aux tests de logique métier, je suis convaincu que plus je me rapproche de la réalité, plus je vais dormir la nuit. –

+0

+1 pour Joel et Patrick, parce que je pense que vous avez tous les deux raison. Bien que je sois d'accord avec Joel sur le fait que le design devrait être comme ça - on ne peut pas prétendre que parfois il suffit d'automatiser quelques contrôles/fenêtres juste parce que certains codes vieux/fragiles/notyours en ont besoin. – quetzalcoatl