如何使用ViewModelLocator进行单元测试

TMa*_*Man 5 wpf unit-testing mvvm viewmodellocator

我已经使用Autofac创建了一个自定义视图模型定位器,并通过App.xaml正常设置它,就像通常使用它们一样.我的问题是我现在如何进行单元测试?每次我尝试测试初始化​​视图的方法时,我都会收到错误

在我的app.xaml中:

<desktop:ViewModelLocator xmlns:local="clr-namespace:MyProject.Desktop" x:Key="ViewModelLocator" />
Run Code Online (Sandbox Code Playgroud)

在每个视图中:

DataContext="{Binding MyFirstViewModel, Source={StaticResource ViewModelLocator}}"
Run Code Online (Sandbox Code Playgroud)

单元测试错误:

{"Cannot find resource named 'ViewModelLocator'. Resource names are case sensitive."}
Run Code Online (Sandbox Code Playgroud)

我明白为什么当你进行单元测试时,确实没有实际应用程序的实例,所以这个问题的好方法是什么?

ViewModelLocator代码:

/// <summary>
/// Autofac object container
/// </summary>
private readonly IContainer objectContainer;

#region Constructor

/// <summary>
/// Constructor for view model locator
/// </summary>
public ViewModelLocator()
{
    objectContainer = App.ObjectContainer;
    //objectContainer.BeginLifetimeScope();
}

#endregion

#region Properties

/// <summary>
/// Gets the resolved instance of a main window view model
/// </summary>
public MainWindowViewModel MainWindowViewModel
{
    get
    {
        return objectContainer.Resolve<MainWindowViewModel>();
    }
}

public FirstViewModel MyFirstViewModel 
{
    get
    {
        return objectContainer.Resolve<FirstViewModel>();
    }
}

public SecondViewModel MySecondViewModel 
{
    get
    {
        return objectContainer.Resolve<SecondViewModel>();
    }
}
Run Code Online (Sandbox Code Playgroud)

den*_*zov 1

这有点晚了,但也许有用。不要在构造函数中解析 objectContainer,而是通过属性来解析:

//note this is a lazy getter, i.e. will be resolved when needed on the first call
private IContainer ObjectContainer
{
   get
   {
       if(objectContainer == null)
           objectContainer = App.ObjectContainer;
       return objectContainer:
   }
}
Run Code Online (Sandbox Code Playgroud)

然后通过代码使用该属性,而不是字段。此外,当我担心其他人使用我想要通过属性使用强制执行的字段时,我会将其重命名为 IntelliSence 中不易识别的名称(例如 zREgdnlksfObjectContainer:))请注意该属性是私有的,因此没有什么真正改变。您可以将该属性设置为内部并将您的库标记为对单元测试可见,以便在单元测试中您可以模拟它以WhenCalled()返回/解析 IContainer。