2011-06-03 1 views
13

После выполнения обоих следующих тестовых примеров на консоль печатается COM-исполнение. Что я делаю не так?Исключения COM при выходе с WPF

Если я запускаю либо тест по отдельности, либо если я запускаю оба теста вместе, исключение записывается на консоль ровно один раз. Это заставляет меня подозревать, что есть какой-то ресурс на AppDomain, который я не очищаю.

Я пробовал тесты с NUnit и с MSTest, с тем же поведением в обеих средах. (На самом деле, я не уверен, что при работе обоих тестов в результатах MSTest в одном исключение распечатке или два.)

Исключение:

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) 

код теста:

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

Может http://social.msdn.microsoft.com/forums/en-US/vststest/thread/e53fdc45-23f3-4aee-aad9-f63769f2c638/ помогает –

+0

К сожалению, я не могу использовать MTA, поскольку WPF требует STA. Создание формы и узла элемента в SetUp тоже не похоже на трюк. Argh. –

+0

Если я не ошибаюсь, это исключение не приводит к сбою unittest, не так ли? Я столкнулся с одним и тем же исключением, когда я удалял элементы управления WPF, я решил игнорировать его.;) – Bubblewrap

ответ

18

Вновь взглянув на мой собственный код, следующая строка может помочь в тестировании WPF прямо в конце.

Dispatcher.CurrentDispatcher.InvokeShutdown(); 
+0

Sweeeeet! Так оно и было. Благодаря! Теперь мне просто нужно разобраться, как поместить это в мою тестовую архитектуру. –

+0

Разочарование, когда диспетчер связан с потоком (то есть Dispatcher.CurrentDispatcher), ни один другой диспетчер не может быть связан с этим потоком. И как только диспетчер был отключен, его нельзя перезапустить. Поэтому, хотя это решает мою проблему, я, к сожалению, не могу просто вызвать вызов InvokeShutdown() в методе TearDown базового тестового класса. –

+0

Попробуйте запустить новый поток STA в каждом unittest, выполните тест в этом новом потоке и дождитесь окончания этой нити Thread.Join(). – Bubblewrap

1

Вы, наверное, можно 't полностью проверит классы Window и Form. Как приложения WinForms, так и приложения WPF имеют класс Application, используемый для запуска базовой сантехники (сообщений насосов и много чего). Держу пари, что это ключ к тому, чтобы избежать этого исключения.

Вы не делаете этого и, возможно, не сможете.

Каждая рекомендация для модульного тестирования, которую я когда-либо читал, заключается в том, что вы рефакторируете так, чтобы классы Form и классы Window ничего не делали для модульного тестирования (например, шаблон M-V-VM в WPF). Может иметь какое-то отношение к тому, чтобы не показывать пользовательский интерфейс.

Есть и другие способы тестирования пользовательского интерфейса. This answer обсуждает пользовательский интерфейс тестирования.

+3

На самом деле тесты проходят нормально - я просто получаю много дерьма в своих файлах журналов. Что касается тестирования пользовательского интерфейса и прямого тестирования логической логики - я полагаю, что чем ближе я доберусь до проверки того, с чем работает пользователь, тем лучше я буду спать по ночам. –

+0

+1 для Джоэля и Патрика, потому что я думаю, что вы оба правы. Хотя я согласен с Джоэлем в том, что дизайн должен быть таким - вы не можете утверждать, что иногда вам просто нужно автоматизировать несколько элементов управления/окон только потому, что ему нужен какой-то старый/хрупкий/notyours код. – quetzalcoatl

 Смежные вопросы

  • Нет связанных вопросов^_^