c# - 单元测试基于 Prism 的 WPF 应用程序
问题描述
我想对基于 Prism 的 WPF 应用程序进行单元测试。这是一个包含多个项目的巨大应用程序。每个项目都基于具有 ViewModel/Views 的 MVVM 设计模式。此应用程序使用 Bootstrapper 进行初始化,使用区域概念并具有事件处理。
我尝试使用 xunit。我拿了一个项目并添加了一个相应的测试项目,我尝试在其中实现一个测试用例。在测试用例中,我创建了一个 View 类的实例(代码隐藏)并尝试从该类调用一个方法。我收到以下错误:
*****************
------ Run test started ------
[xUnit.net 00:00:00.3423646] Discovering: Demo.Test
[xUnit.net 00:00:01.2217151] Discovered: Demo.Test
[xUnit.net 00:00:01.2260195] Starting: Demo.Test
[xUnit.net 00:00:02.5700093] TestClassLibrary.TestDemo.TestCase1 [FAIL]
[xUnit.net 00:00:02.5722687] System.InvalidOperationException : The calling thread must be STA, because many UI components require this.
[xUnit.net 00:00:02.5739943] Stack Trace:
[xUnit.net 00:00:02.5749537] at System.Windows.Input.InputManager..ctor()
[xUnit.net 00:00:02.5754038] at System.Windows.Input.InputManager.GetCurrentInputManagerImpl()
[xUnit.net 00:00:02.5757829] at System.Windows.Input.KeyboardNavigation..ctor()
[xUnit.net 00:00:02.5762326] at System.Windows.FrameworkElement.FrameworkServices..ctor()
[xUnit.net 00:00:02.5766521] at System.Windows.FrameworkElement.EnsureFrameworkServices()
[xUnit.net 00:00:02.5771316] at System.Windows.FrameworkElement..ctor()
[xUnit.net 00:00:02.5775379] at System.Windows.Controls.Control..ctor()
[xUnit.net 00:00:02.5792034] at System.Windows.Controls.UserControl..ctor()
[xUnit.net 00:00:02.5796505] at Demo.Views.DemoLandingPage..ctor(IDemoViewModel vwModel, IEventAggregator eventAggregator, ISharedService sharedService)
[xUnit.net 00:00:02.5801319] Demo.Test\Class1.cs(65,0): at TestClassLibrary.TestDemo.<TestCase1>b__0_0()
[xUnit.net 00:00:02.5805993] at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
[xUnit.net 00:00:02.5810366] at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
[xUnit.net 00:00:02.5814870] at System.Windows.Threading.DispatcherOperation.InvokeImpl()
[xUnit.net 00:00:02.5819703] at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
[xUnit.net 00:00:02.5825284] at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
[xUnit.net 00:00:02.5831148] at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
[xUnit.net 00:00:02.5834395] at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
[xUnit.net 00:00:02.5837782] at MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContext executionContext, ContextCallback callback, Object state)
[xUnit.net 00:00:02.5842970] at System.Windows.Threading.DispatcherOperation.Invoke()
[xUnit.net 00:00:02.5848709] at System.Windows.Threading.Dispatcher.ProcessQueue()
[xUnit.net 00:00:02.5852488] at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
[xUnit.net 00:00:02.5857359] at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
[xUnit.net 00:00:02.5863023] at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
[xUnit.net 00:00:02.5867150] at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
[xUnit.net 00:00:02.5872700] at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
[xUnit.net 00:00:02.5877817] at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
[xUnit.net 00:00:02.5883386] at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
[xUnit.net 00:00:02.5889004] at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
[xUnit.net 00:00:02.5894200] at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
[xUnit.net 00:00:02.5899856] at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
[xUnit.net 00:00:02.5905323] at System.Windows.Threading.DispatcherOperation.Wait(TimeSpan timeout)
[xUnit.net 00:00:02.5910927] at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherOperation operation, CancellationToken cancellationToken, TimeSpan timeout)
[xUnit.net 00:00:02.5915975] at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
[xUnit.net 00:00:02.5921129] Demo.Test\Class1.cs(63,0): at TestClassLibrary.TestDemo.TestCase1()
[xUnit.net 00:00:02.6178918] Finished: Demo.Test
========== Run test finished: 1 run (0:00:03.1364452) ==========
*****************
这是测试用例代码:
************* Class1.cs ******
namespace TestClassLibrary
{
public class TestDemo
{
[Fact]
public void TestCase1()
{
if (Application.Current == null)
{
if (System.Windows.Application.Current == null)
{
new System.Windows.Application { ShutdownMode = ShutdownMode.OnExplicitShutdown };
}
}
(LINE 63) Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
{
(LINE 65) DemoLandingPage dem = new DemoLandingPage(null, null, null);
List<string> countryList = dem.GetCountryList("CountryList");
bool ret = searchCountry("Test", countryList);
Assert.True(ret == true);
}));
}
bool searchCountry(string country, List<string> list)
{
return list.Contains(country);
}
*************
我想知道:
是否可以对基于 Prism 的 WPF 应用程序进行单元测试?如果是这样,您能否让我知道我应该采用什么方法来测试此应用程序。任何指针或文档/链接都会有很大帮助。
谢谢
解决方案
推荐阅读
- mysql - 谷歌云平台 - 来自具有公共 IP 的计算引擎实例的 mySQL 访问被拒绝
- java - Java 将 object 类型的 ArrayList 转换为 object 类型的另一个 ArrayList
- chisel - Chisel3: Vec indexWhere 预期 Bool,实际 Any
- ios - 在 xcode 11.6 中反应原生崩溃
- c++ - 在 ubuntu 环境中为 c++ 配置 Netbeans IDE
- javascript - 根据父组件中的值动态加载名称
- java - 使用 Java 流将哈希图收集到 ArrayList 时出现 ConcurrentModificationException
- angular - Angular 9 组件库参考
- sql - 如何使用 SQL 获得通过和失败的学生?
- oracle-apex - 如何以编程方式更改 Oracle Apex 图表类型