我如何单元测试,一个视图模型发送正确的字符串到另一个视图模型?

时间:2019-03-25 16:02:53

标签: c# unit-testing mvvm xamarin.forms moq

在视图模型的构造函数中,我有一个调用方法的命令声明:

OpenGroupCommand = new DelegateCommand(OnOpenGroupExecute);

该方法如下:

private void OnOpenGroupExecute(object obj)
        {
            string groupName = (string)obj;
            Application.Current.MainPage.Navigation.PushAsync(new GroupPage(groupName));
        }

如何测试groupName是否正确传递给另一个视图模型?在另一个视图模型中,将groupName参数发送到VM实例上的GroupName属性:

public class GroupPageViewModel : ViewModelBase, IGroupPageViewModel
    {
        private string _groupName;
        public GroupPageViewModel(string groupName)
        {
            LoadGroupName(groupName);
        }
        public void LoadGroupName(string groupName)
        {
            GroupName = groupName;
        }
        public string GroupName
        {
            get
            {
                return _groupName;
            }
            set
            {
                _groupName = value;
                OnPropertyChanged();
            }
        }
    }

在调试时一切正常,但是如何进行单元测试?即使使用Moq框架,我在哪里可以读到一些有关测试和模拟的东西?

2 个答案:

答案 0 :(得分:0)

我相信您的问题实际上是关于如何测试页面之间的导航的。

在方法OnOpenGroupExecute的实现中,由于您使用Xamarin表单来实现导航,因此必须在测试项目中引用Xamarin Forms程序集,这使得单元测试依赖于Xamarin Forms。

按照本文档https://docs.microsoft.com/en-us/xamarin/xamarin-forms/enterprise-application-patterns/中的建议,尝试创建一个导航界面并使用viewmodel导航(有关https://github.com/dotnet-architecture/eShopOnContainers的更多详细信息)

然后在您的单元测试项目中,实现如下所示的伪造的导航服务类,并将其注入DI容器中:

public class FakeNavigationService : INavigationService //this interface is from MS eShopOnContainer project
{
    private List<ViewModelBase> _viewModels = new List<ViewModel>();

    public Task NavigateToAsync<TViewModel>() where TViewModel : ViewModelBase {
        //create viewModel object from DI container
        //var viewModel = ......
        _viewModels.Add(viewModel);
    }

    public ViewModelBase CurrentPageViewModel {
        get {
            if (_viewModels.Count() < 1) {
                return null;
            }
            return _viewModels[_viewModels.Count() - 1];
        }
    }
}

这只是一个建议。如果您已在应用程序中实现了大多数功能,则需要花费一些时间才能将“页面导航”更改为“视图导航”模型。

答案 1 :(得分:0)

好吧,让我们看看您拥有什么:

  1. 您在私有方法中有一些代码,除非您将该代码公开,否则您将无法直接对其进行测试,因为您无法对其进行调用。我在这里没有考虑让您调用私有方法的任何技巧。

  2. 该方法做什么?根本不清楚,它收到一个对象,我们不知道其中有什么。您正在将其转换为字符串,但是如果它不是字符串呢?您可以将该对象转换为字符串吗?谁知道。

因此,我们有一个方法,我们不知道它的作用,我们不知道它作为参数接收什么,我们不能直接调用它,但是我们想对其进行测试。这不是一个好位置。

退后一步,问自己,您到底要测试什么?

您说过:如何测试是否将groupName正确传递给另一个视图模型?

“正确”是什么意思?您需要定义该字符串正确的含义。这将提供您可以使用的测试方案。

我希望收到一个看起来像A的对象,我想将其转换为一个看起来像B的字符串。暂时不用考虑视图模型,那只是无关紧要的噪音。

您可以将方法更改为公共方法,并且可以测试对于不同类型的输入数据,您将获得正确的结果。从字面上看,这是在处理对象并从中提取一些东西。如果该方法正确,则可以保证视图模型将接收正确的输入,并且从单元测试的角度来看,这已经足够了。

您当然可以为各种输入添加更多测试,可以测试正确的故障条件等。