13

执行以下两个测试用例后,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();
        }
    }
}
4

2 回答 2

20

再次查看我自己的代码,以下行可能有助于 WPF 测试,就在最后。

Dispatcher.CurrentDispatcher.InvokeShutdown();
于 2011-06-04T11:25:50.563 回答
1

您可能根本无法对WindowandForm类进行单元测试。WinForms 应用程序和 WPF 应用程序都有一个Application用于启动底层管道(消息泵等)的类。我敢打赌,这是避免该异常的关键。

你没有在那里做,可能做不到。

我读过的每条单元测试建议都是重构,这样Form类和Window类就不会做单元测试所需的任何事情(如 WPF 中的 MV-VM 模式)。可能与无法显示 UI 有关。

还有其他方法可以测试 UI。这个答案讨论了单元测试 UI。

于 2011-06-04T01:58:02.650 回答