C# Win10 UWP、Prism/Unity和单元测试加类库、静默故障

C# Win10 UWP、Prism/Unity和单元测试加类库、静默故障,c#,unit-testing,unity-container,prism,uwp,C#,Unit Testing,Unity Container,Prism,Uwp,基本布局目前是一个简单的应用程序。没什么特别的,我在App.Views命名空间中有视图,在App.ViewModels命名空间中有我的ViewModels。ViewModels通过XAML指令自动连接到视图: xmlns:prismMvvm="using:Prism.Windows.Mvvm" prismMvvm:ViewModelLocator.AutoWireViewModel="True" 所以,基本上,这是可行的。然后我想利用Unity的IoC/DependencyInjection进

基本布局目前是一个简单的应用程序。没什么特别的,我在
App.Views
命名空间中有视图,在
App.ViewModels
命名空间中有我的ViewModels。ViewModels通过XAML指令自动连接到视图:

xmlns:prismMvvm="using:Prism.Windows.Mvvm"
prismMvvm:ViewModelLocator.AutoWireViewModel="True"
所以,基本上,这是可行的。然后我想利用Unity的IoC/DependencyInjection进行一些单元测试

通常的方法是简单地将Windows10单元测试应用程序添加到现有应用程序中,并在单元测试应用程序中引用后者

这将在执行单元测试时崩溃,因为您可能无法从
应用程序
之外的任何其他对象派生
应用程序
类。 也就是说,这项工作:

public sealed partial class App : Application
这并不是:

public sealed partial class App : PrismUnityApplication
这可能也不是Prism的错,微软必须解决这一问题

现在,建议的解决方法是简单地将想要进行单元测试的内容放入类库中,并从单元测试应用程序引用该库。这适用于单元测试。它也适用于模型

然而,对于ViewModels,我的天真方法不起作用。ViewModel类仍然可以在
App.ViewModels
命名空间下找到,与以前一样,只是它们现在位于类库中。我可以在主应用程序中以编程方式访问它们。但在运行程序时,自动布线会自动失败,不会出现错误

即使我做了这样的事情,它仍然不起作用:

ViewModelLocationProvider.Register(typeof(MainPage).ToString(), () => new ViewModels.MainPageViewModel());
我对所涉及的技术还不是很有经验,所以如果没有实际的错误,我有点不知所措

编辑:只是为了增加神秘性-无论ViewModel位于主应用程序还是类库中,此代码都可以工作:

var x = Container.Resolve(typeof(ExamplePageViewModel)) as ExamplePageViewModel;

您是正确的,这通常是UWP应用程序可测试性的一个限制。UWP应用程序的可测试性目前还不完善。为了解决第一个问题,需要将BindableAttribute添加到应用程序类中:

[Bindable]
sealed partial class App : PrismUnityApplication
{

}

至于将视图/视图模型拉出到单独的程序集中,这个问题是由于UWP如何处理来自单独程序集中的加载类型。尽管如此,这不应该阻止您测试ViewModels。您可以使用常规类库来测试ViewModel逻辑。您将模拟您的依赖关系。您不应该创建视图实例来测试ViewModels。因此ViewModelLocator不再是问题。

我们遇到了与您相同的问题,测试失败。 当我们查看测试输出窗口时,我们看到:

App activation failed.
Failed to initialize client proxy: could not connect to test process.
在继承[PrimunityApplication]的[UnitTestApp]中,我们重写[ConfigureContainer]方法,并在容器上设置模拟,而不是设置实际类,即

UnitTestApp.Current.Container.RegisterInstance(myMock.Object, new ContainerControlledLifetimeManager());
您还可以在每个测试类的构造函数中设置容器 通过这种方式,我们使测试运行时没有出现无声的失败

无声故障似乎是由于实际应用程序类的容器在UnitTestApp类的上下文中被调用所致,但我无法100%确认