COM-исключения при выходе с WPF - PullRequest
13 голосов
/ 04 июня 2011

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

Если я запускаю один тест по отдельности или оба теста вместе, исключение записывается на консоль ровно один раз.Это заставляет меня заподозрить, что есть какой-то ресурс для 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();
        }
    }
}

Ответы [ 2 ]

19 голосов
/ 04 июня 2011

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

Dispatcher.CurrentDispatcher.InvokeShutdown();
1 голос
/ 04 июня 2011

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

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

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

Существуют и другие способы проверки пользовательского интерфейса. В этом ответе обсуждается пользовательский интерфейс модульного тестирования.

...