COM-исключения при выходе с WPF
После выполнения обоих следующих тестовых случаев выполнение COM выводится на консоль. Что я делаю неправильно?
Если я запускаю либо тест по отдельности, либо одновременно запускаю оба теста, исключение записывается в консоль ровно один раз. Это заставляет меня подозревать, что есть какой-то ресурс для каждого домена приложений, который я не очищаю.
Я пробовал тесты с 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 ответа
Посмотрев на мой собственный код еще раз, следующая строка может помочь для теста WPF, прямо в конце.
Dispatcher.CurrentDispatcher.InvokeShutdown();
Вы, вероятно, не можете юнит тестировать Window
а также Form
классы вообще. Как приложения WinForms, так и приложения WPF имеют Application
класс используется для запуска основной сантехники (сообщения насосов и еще много чего). Бьюсь об заклад, это ключ к тому, чтобы избежать этого исключения.
Вы там этого не делаете и, возможно, не сможете.
Каждая рекомендация по модульному тестированию, которую я когда-либо читал, заключается в том, чтобы вы Form
классы и Window
классы не делают ничего, что вам нужно для модульного тестирования (например, шаблон MV-VM в WPF). Может быть как-то связано с невозможностью показать пользовательский интерфейс.
Есть и другие способы проверить пользовательский интерфейс. Этот ответ обсуждает пользовательский интерфейс модульного тестирования.