Reputation: 9015
when unit-testing using MSTest, I create a WPF window. When this window closes, Visual Studio shows InvalidComObjectException
:
COM object that has been separated from its underlying RCW cannot be used.
it is raised after the [TestMethod]
exits, and the stack contains only external code (no InnerException
). This is what I have:
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}
And this is the code that creates the window:
var myWindow = new SomeWindow(errors);
myWindow.ShowDialog();
The window contains two ListView
s with some text elements and check-boxes in them
Upvotes: 3
Views: 1285
Reputation: 33506
I've stumbled upon this some time ago. If I recall correctly, it is because between the tests the default Dispatcher for your AppDomain is not properly cleaned up and reinitialized.
To solve it, I've created a DomainNeedsDispatcherCleanup
attribute class that takes care of proper setup&teardown of the Dispatcher. I'll include it here as soon as I find it, but mind that I use XUnit, not MSTest.
EDIT: Just found it. Here you go:
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();
}
}
}
Hahha.. So, as you see, the fix is trivial. I did not remember that. Surely, you just need to InvokeShutdown
in your teardown and it should be fixed.
Upvotes: 6