执行以下两个测试用例后,将向控制台打印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();
}
}
}
答案 0 :(得分:19)
再次查看我自己的代码,最后一行可能有助于WPF测试。
Dispatcher.CurrentDispatcher.InvokeShutdown();
答案 1 :(得分:1)
您可能根本无法对Window
和Form
类进行单元测试。 WinForms应用程序和WPF应用程序都有一个Application
类用于启动底层管道(消息泵等等)。我敢打赌,这是避免这种异常的关键。
你不是那样做的,可能无法做到。
我读过的每一个单元测试建议都是你重构,以便Form
类和Window
类不做单元测试所需的任何事情(比如MV-VM模式)在WPF)。可能与无法显示UI有关。
还有其他方法可以测试用户界面。 This answer讨论了单元测试用户界面。