如何测试使用其 ViewDispatcher 属性的 MvvmCross ViewModel

本文关键字:ViewDispatcher 属性 ViewModel MvvmCross 何测试 测试 | 更新日期: 2023-09-27 17:56:07

我有一个继承自MvxBase的 MvvmCross ViewModel,并使用其ViewDispatcher属性,如下所示:

    /// Handles a timer elapsed event
    private void TimerOnElapsed(object sender, EventArgs eventArgs)
    {
      ViewDispatcher.RequestMainThreadAction(UpdateEllapsedTime);
    }

问题是当我尝试在单元测试中使用此视图模型时,ViewDispatcher 为空。 我正在测试中创建和注册模拟调度程序,但 ViewModel 的 ViewDispatcher 属性是由框架中的父类MvxMainThreadDispatcher.Instance而不是从 IoC 容器解析的。

我当前使用的解决方法如下:

    private void TimerOnElapsed(object sender, EventArgs eventArgs)
    {
        if (ViewDispatcher != null)
        {
            ViewDispatcher.RequestMainThreadAction(UpdateEllapsedTime);
        }
        else
        {
            UpdateEllapsedTime();
        }
    }

我不想将代码添加到类中的唯一目的是让单元测试工作,但我认为在这种情况下这没什么大不了的。 但是,我仍然想知道是否有更好的方法可以使此ViewModel可测试。

如何测试使用其 ViewDispatcher 属性的 MvvmCross ViewModel

>ViewDispatcher作为优化缓存在MvxMainThreadDispatcher.Instance引用中(也是因为一些遗留原因)。

但是,它仍然在IOC系统中注册。

要在单元测试中使用它,最简单的方法是使用模拟调度程序,例如 n29 MvvmCross 视频 - https://github.com/MvvmCross/NPlus1DaysOfMvvmCross/blob/master/N-29-TipCalcTest/TipCalcTest.Tests/MockDispatcher.cs

此单例是使用以下代码创建和注册的:

var mockDispatcher = new MockDispatcher();
        Ioc.RegisterSingleton<IMvxViewDispatcher>(mockDispatcher);
        Ioc.RegisterSingleton<IMvxMainThreadDispatcher>(mockDispatcher);

并且可以在测试中使用ClearAll()清除MvxIoCSupportingTest


如果您认为这应该在将来的 Mvx 版本中清理,那么 https://github.com/MvvmCross/MvvmCross/issues/542 上有一个未解决的问题 - 人们可以在那里发表评论和贡献