基本布局当前是一个简单的应用。没什么好想的,我在App.Views
命名空间中有Views,在App.ViewModels
命名空间中有ViewModels。通过XAML指令将ViewModel自动连接到视图:
xmlns:prismMvvm="using:Prism.Windows.Mvvm"
prismMvvm:ViewModelLocator.AutoWireViewModel="True"
因此,基本上,这可行。然后,我想利用Unity的IoC / DependencyInjection进行一些单元测试。
通常的方法是将Windows 10单元测试应用程序简单地添加到现有应用程序,并在单元测试应用程序中引用后者。
这将在执行单元测试时崩溃,因为似乎您可能无法从App
之外的任何事物派生Application
类。即这有效:
public sealed partial class App : Application
这不是:
public sealed partial class App : PrismUnityApplication
这可能也不是Prism的错,这是微软必须最终解决的问题。
现在,建议的解决方法是将要进行单元测试的所有内容简单地放入类库中,并从单元测试应用程序中引用该库。这适用于单元测试。它也适用于模型。
但是,我的幼稚方法不适用于ViewModels。与以前一样,仍然在App.ViewModels
命名空间下找到ViewModel类,只是它们现在位于类库中。我可以在主应用中以编程方式访问它们。但是,在运行该程序时,自动装配将无提示地自动失败,没有错误。
即使我做这样的事情,它仍然不起作用:
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
{
}
就将Views / ViewModels拉到单独的程序集中而言,此问题是由于UWP如何处理从单独的程序集加载的类型。但是,这不应阻止您测试ViewModel。您可以使用常规的类库来测试ViewModel逻辑。您将模拟依赖项。您不应该创建View的实例来测试ViewModel。因此,ViewModelLocator变为非问题。
我们遇到了与您相同的问题,无声地测试失败。当我们查看“测试输出”窗口时,我们看到了:
App activation failed.
Failed to initialize client proxy: could not connect to test process.
在继承了[PrismUnityApplication]的[UnitTestApp]内部,我们重写了[ConfigureContainer]方法,并在容器上设置了模拟程序,而不是设置真实的类,即
UnitTestApp.Current.Container.RegisterInstance(myMock.Object, new ContainerControlledLifetimeManager());
通过这种方式,我们的测试得以顺利进行,而没有出现失败。
似乎无声失败是由于实际的App类的容器在UnitTestApp类的上下文中被调用-但我无法100%确认
希望这会有所帮助