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

时间:2014-04-02 15:00:08

标签: c# unit-testing xamarin.android xamarin mvvmcross

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

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

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

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

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

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

1 个答案:

答案 0 :(得分:2)

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就会有一个未解决的问题 - 人们可以在那里发表评论并做出贡献