Как выполнить модульное тестирование с использованием ViewModelLocator

Я создал пользовательский локатор модели представления с помощью Autofac и настроил его обычно через App.xaml, как обычно используется большинство из них. Моя проблема в том, как мне сейчас выполнить юнит-тест? Я получаю сообщение об ошибке каждый раз, когда пытаюсь протестировать метод, который инициализирует представление

В моем app.xaml:

<desktop:ViewModelLocator xmlns:local="clr-namespace:MyProject.Desktop" x:Key="ViewModelLocator" />

В каждом представлении:

DataContext="{Binding MyFirstViewModel, Source={StaticResource ViewModelLocator}}"

Ошибка модульного теста:

{"Cannot find resource named 'ViewModelLocator'. Resource names are case sensitive."}

Я понимаю, почему, когда вы проводите модульное тестирование, на самом деле не существует экземпляра реального приложения, так что же, как решить эту проблему?

ViewModelLocator Code:

/// <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>();
    }
}

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:
   }
}

Затем используйте свойство через код, а не поле. Также, когда я беспокоюсь о том, чтобы кто-то еще использовал поле, которое я хочу применить через использование свойства, я переименовал бы его в нечто, что не было бы легко узнать в IntelliSence (например, zREgdnlksfObjectContainer:)). Обратите внимание, что свойство является закрытым, поэтому на самом деле ничего не меняется. Вы можете сделать свойство внутренним и пометить вашу библиотеку как видимую для вашего модульного теста, чтобы в модульном тесте вы могли ее WhenCalled() возврат / разрешение IContainer.

Другие вопросы по тегам