我正在使用Prism和Xamarin Forms创建一个应用程序。我想对我的视图模型进行单元测试。
我有一个导航到页面的命令。我想声明在调用该命令后导航发生在右页。
我想我需要复制Prism/Source/Xamarin/Prism.Forms.Tests/Navigation/PageNavigationServiceFixture.cs文件中的代码。
例如,查看此方法(来自PageNavigationServiceFixture类):
public async void Navigate_ToContentPage_ByName()
{
var navigationService = new PageNavigationServiceMock(_container, _applicationProvider, _loggerFacade);
var rootPage = new Xamarin.Forms.ContentPage();
((IPageAware)navigationService).Page = rootPage;
await navigationService.NavigateAsync("ContentPage");
Assert.True(rootPage.Navigation.ModalStack.Count == 1);
Assert.IsType(typeof(ContentPageMock), rootPage.Navigation.ModalStack[0]);
}
它创建导航服务,导航到页面,然后断言页面已更改。
现在这是我的测试类:
[TestClass]
public class MenuPrincipalViewModelTests
{
[TestMethod]
public void AProposCommand()
{
INavigationService navigationService = new PageNavigationServiceMock(_container, _applicationProvider, _loggerFacade);
// 1: Here I need to initialize my navigation service to my MasterDetailPage
MenuPrincipalPageViewModel viewModel = new MenuPrincipalPageViewModel(navigationService);
viewModel.AProposCommand.Execute();
// 2: Here I want to assert that the new navigation stack is MenuPrincipalPage/ContenuPage/AProposPage
}
PageNavigationContainerMock _container;
IApplicationProvider _applicationProvider;
ILoggerFacade _loggerFacade;
public MenuPrincipalViewModelTests()
{
_container = new PageNavigationContainerMock();
_container.Register("PageMock", typeof(PageMock));
_container.Register("ContentPage", typeof(ContentPageMock));
_container.Register(typeof(ContentPageMockViewModel).FullName, typeof(ContentPageMock));
_container.Register("NavigationPage", typeof(NavigationPageMock));
_container.Register("NavigationPage-Empty", typeof(NavigationPageEmptyMock));
_container.Register("NavigationPageWithStack", typeof(NavigationPageWithStackMock));
_container.Register("NavigationPageWithStackNoMatch", typeof(NavigationPageWithStackNoMatchMock));
_container.Register("MasterDetailPage", typeof(MasterDetailPageMock));
_container.Register("MasterDetailPage-Empty", typeof(MasterDetailPageEmptyMock));
_container.Register("TabbedPage", typeof(TabbedPageMock));
_container.Register("CarouselPage", typeof(CarouselPageMock));
_container.Register("MenuPrincipalPage", typeof(MenuPrincipalPage));
_container.Register("ContenuPage", typeof(ContenuPage));
_container.Register("ClubHousePage", typeof(ClubHousePage));
_container.Register("AProposPage", typeof(AProposPage));
_applicationProvider = new ApplicationProviderMock();
_loggerFacade = new EmptyLogger();
}
}
构造函数是从PageNavigationServiceFixture复制的。我现在需要实施AProposCommand测试,我有2个问题(在代码中注明)
如何初始化导航服务模拟以便复制我的应用程序?有关信息,请参阅我的App类:
public partial class App : PrismApplication
{
public App(IPlatformInitializer initializer = null) : base(initializer) { }
protected override void OnInitialized()
{
InitializeComponent();
NavigationService.NavigateAsync("MenuPrincipalPage/ContenuPage/ClubHousePage");
}
protected override void RegisterTypes()
{
Container.RegisterTypeForNavigation<MenuPrincipalPage>();
Container.RegisterTypeForNavigation<ClubHousePage>();
Container.RegisterTypeForNavigation<AProposPage>();
Container.RegisterTypeForNavigation<ContenuPage>();
}
}
MenuPrincipalPage是MasterDetailPage,ContenuPage是NavigationPage。
我的第二个问题是:如何断言导航堆栈现在是 MenuPrincipalPage / ContenuPage / ClubHousePage ?
非常感谢您阅读所有内容并获得答案!!! 于连
答案 0 :(得分:5)
你建议的是对Prism进行单元测试而不是你的代码。对ViewModel进行单元测试是一件好事,但您只需提供一个Mock,它可以为您提供验证预期导航字符串/参数是否有效的方法。例如,你的模拟可能看起来像:
public class MockNavigationService : INavigationService
{
public string LastNavigationString { get; private set; }
public NavigationParameters LastNavigationParameters { get; private set; }
public Task NavigateAsync(string name, NavigationParameters parameters, bool? useModalNavigation = null, bool animated = true)
{
LastNavigationString = name;
LastNavigationParameters = parameters;
return Task.FromResult(0);
}
}
对我而言,我的真正目标不是运行单元测试,而是运行可以验证应用程序的导航和用户体验的UITest。