MvvmCross 中的导航单元测试

Navigation Unit Testing in MvvmCross

尝试在我的一个命令调用中对导航进行单元测试,调用一个私有方法。只是尝试测试导航请求是否已作为此命令执行的结果发出。

有旧文档; https://www.mvvmcross.com/documentation/fundamentals/testing

据我所知,本文档并未考虑新的基于异步的调用;例如 IMvxMainThreadAsyncDispatcher 要么我们需要实现两个ExecuteOnMainThreadAsync方法,要么在MockDispatcher中继承MvxMainThreadAsyncDispatcher。

还需要在IoC注册中添加IMvxMainThreadAsyncDispatcher

var mockDispatcher = new MockDispatcher();

...

...

Ioc.RegisterSingleton<IMvxMainThreadAsyncDispatcher>(MockDispatcher);

因此,除了导航调用请求外,几乎所有测试都有效。 MockDispatcher 中的以下方法永远不会被调用,所以我无法检查请求计数;

public async Task<bool> ShowViewModel(MvxViewModelRequest request)
{
     Requests.Add(request);
     return true;
}

有人有可以模拟并以其他形式调用此请求的工作代码吗? IMvxMainThreadDispatcher 被设置为绝对的,并且在 MVVMCross 中不再使用 ShowViewModel<>() 完成导航调用,它是通过调用 navigationService.Navigate();

完成的

好吧,我找到了我的问题的解决方案...当导航服务被正确模拟时,将调用 ShowViewModel。我在 GitHub 上从 MvvmCross 自己的回购中找到了一段关于他们如何进行导航测试的代码。我的下一个挑战是模拟目标 viewModel,但这是单独的,下面的代码没有涵盖它。以前我有一个非常基本的 IMvxNavigationService 模拟。

var mockLocator = new Mock<IMvxViewModelLocator>();
mockLocator.Setup(
                m => m.Load(It.IsAny<Type>(), It.IsAny<IMvxBundle>(), It.IsAny<IMvxBundle>(), It.IsAny<IMvxNavigateEventArgs>())).Returns(() => new FakeViewModel());
mockLocator.Setup(
                m => m.Reload(It.IsAny<IMvxViewModel>(), It.IsAny<IMvxBundle>(), It.IsAny<IMvxBundle>(), It.IsAny<IMvxNavigateEventArgs>())).Returns(() => new FakeViewModel());

var mockCollection = new Mock<IMvxViewModelLocatorCollection>();
mockCollection.Setup(m => m.FindViewModelLocator(It.IsAny<MvxViewModelRequest>()))
                .Returns(() => mockLocator.Object);

Ioc.RegisterSingleton(mockLocator.Object);

var loader = new MvxViewModelLoader(mockCollection.Object);

_navigationService = new MvxNavigationService(null, loader)
{
      ViewDispatcher = MockDispatcher,
};
_navigationService.LoadRoutes(new[] { typeof(YourViewModelTestClass).Assembly });
Ioc.RegisterSingleton<IMvxNavigationService>(_navigationService);