Win10 UWP, Prism / Unity и модульные тесты плюс библиотеки классов, тихий сбой

Базовый макет в настоящее время представляет собой простое приложение. Ничего особенного, у меня есть представления в пространстве имен App.Views и мои модели представления в пространстве имен App.ViewModels. ViewModels автоматически подключается к представлениям через директиву XAML:

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 и что-то Microsoft должна исправить со своей стороны.

Теперь предлагаемый обходной путь - просто поместить все, что вы хотите для модульного тестирования, в библиотеку классов и ссылаться на эту библиотеку из приложения для модульного тестирования. Это работает для модульного тестирования. Это также работает для моделей.

Однако мой наивный подход не работает для ViewModels. Классы ViewModel по-прежнему находятся в пространстве имен App.ViewModels, как и раньше, но теперь они находятся в библиотеке классов. Я могу получить к ним программный доступ в основном приложении. Но при запуске программы AutoWiring молча выходит из строя без ошибок.

Даже когда я делаю что-то подобное, это все равно не работает:

ViewModelLocationProvider.Register(typeof(MainPage).ToString(), () => new ViewModels.MainPageViewModel());

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

edit: Просто чтобы добавить к тайне - этот код действительно работает, независимо от того, находится ли ViewModel в основном приложении или в библиотеке классов:

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

person Rhywden    schedule 22.11.2015    source источник


Ответы (2)


Вы правы, это ограничение тестируемости приложения UWP в целом. Тестируемость приложений UWP сейчас несовершенна. Чтобы исправить первую проблему, вам нужно добавить BindableAttribute в свой класс приложения:

[Bindable]
sealed partial class App : PrismUnityApplication
{

}

Что касается выделения ваших представлений / моделей представления в отдельные сборки, эта проблема связана с тем, как UWP обрабатывает типы загрузки из отдельных сборок. Тем не менее, это не должно останавливать вас от тестирования ваших ViewModels. Вы можете использовать обычную библиотеку классов для проверки своей логики ViewModel. Вы будете издеваться над своими зависимостями. Вы не должны создавать экземпляры ваших представлений для тестирования ваших ViewModels. Таким образом, ViewModelLocator перестает быть проблемой.

person Community    schedule 22.11.2015

У нас та же проблема, что и у вас, тест не проходит. когда мы посмотрели в окно вывода теста, мы увидели следующее:

App activation failed.
Failed to initialize client proxy: could not connect to test process.

Внутри нашего [UnitTestApp], который наследует [PrismUnityApplication], мы переопределяем метод [ConfigureContainer] и настраиваем макеты контейнера вместо настройки реальных классов, т.е.

UnitTestApp.Current.Container.RegisterInstance(myMock.Object, new ContainerControlledLifetimeManager());

У вас также может быть настройка контейнера в конструкторе каждого тестового класса. Таким образом, мы запустили наш тест без тихой ошибки.

Казалось, что тихий сбой произошел из-за того, что контейнер фактического класса App был вызван в контексте класса UnitTestApp, но я не могу подтвердить 100%

person houss    schedule 02.04.2020