Как выполнить модульное тестирование с использованием 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.