3

当使用 MSTest 进行单元测试时,我创建了一个 WPF 窗口。当此窗口关闭时,Visual Studio 显示InvalidComObjectException

COM object that has been separated from its underlying RCW cannot be used.

它在退出[TestMethod]引发,并且堆栈仅包含外部代码(否InnerException)。这就是我所拥有的:

StackTrace:
       at System.Windows.Input.TextServicesContext.StopTransitoryExtension()
       at System.Windows.Input.TextServicesContext.Uninitialize(Boolean appDomainShutdown)
       at System.Windows.Input.TextServicesContext.TextServicesContextShutDownListener.OnShutDown(Object target, Object sender, EventArgs e)
       at MS.Internal.ShutDownListener.HandleShutDown(Object sender, EventArgs e)

DeclaringType:
    {Name = "TextServicesContext" FullName = "System.Windows.Input.TextServicesContext"}

    Assembly:
        {PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35}

这是创建窗口的代码:

var myWindow = new SomeWindow(errors);
myWindow.ShowDialog();

该窗口包含两个ListViews,其中包含一些文本元素和复选框

4

1 回答 1

6

我前段时间偶然发现了这一点。如果我没记错的话,那是因为在测试之间,您的 AppDomain 的默认调度程序没有正确清理和重新初始化。

为了解决这个问题,我创建了一个DomainNeedsDispatcherCleanup属性类,负责正确设置和拆卸 Dispatcher。我一找到它就会将它包含在此处,但请注意我使用的是 XUnit,而不是 MSTest。

编辑:刚刚找到它。干得好:

using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Threading;
using Xunit;

namespace Boost.Utils.Testing.XUnit.WPF
{
    /// <summary>helful if you stumble upon 'object disconnected from RCW' ComException *after* the test suite finishes,
    /// or if you are unable to start the test because the VS test runner tells you 'Unable to start more than one local run'
    /// even if all tests seem to have finished</summary>
    /// <remarks>only to be used with xUnit STA worker threads</remarks>
    [AttributeUsage(AttributeTargets.Method)]
    public class DomainNeedsDispatcherCleanupAttribute : BeforeAfterTestAttribute
    {
        public override void After(MethodInfo methodUnderTest)
        {
            base.After(methodUnderTest);

            Dispatcher.CurrentDispatcher.InvokeShutdown();
        }
    }
}

哈哈.. 所以,如您所见,修复是微不足道的。我不记得了。当然,你只需要InvokeShutdown在你的拆解中,它应该被修复。

于 2013-06-19T14:52:32.627 回答