我应该在视图模型上对方法或命令进行单元测试吗?

时间:2012-07-13 06:12:46

标签: .net wpf mvvm viewmodel view-model-pattern

我刚看完Jason Dolinger's video on MVVM,我想澄清一下如何正确设置和单元测试我的视图模型的ICommand属性。

考虑以下带有FooBarCommand ICommandProperty的ViewModel类。

public class ViewModel : IViewModel
{
    public ICommand FooBarCommand { get; private set; }

    public bool CanExectuteFooBar()
    {
        return true;
    }

    public void FooBar()
    {
        //Do some FooBarish stuff
    }
}

public interface IViewModel
{
    void FooBar();
    System.Windows.Input.ICommand FooBarCommand { get; }
}

public class FooBarCommand : ICommand
{
    private ViewModel vm;

    public FooBarCommand(ViewModel vm)
    {
        this.vm = vm;
    }
    public bool CanExecute(object parameter)
    {
        return vm.CanExectuteFooBar();
    }

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
        vm.FooBar();
    }
}

因此,如果我单元测试ViewModel的FooBar功能,我可以通过调用testVM.FooBar()或通过调用testVM.FooBarCommand.Execute()执行命令来运行FooBar()。哪个更受欢迎?我倾向于测试FooBarCommand属性,因为最终视图上的按钮被绑定到FooBarCommand属性而不是FooBar()方法。

另外,由于我的View将绑定到IViewModel而不是ViewModel,我应该能够从IViewModel接口中省略FooBar()方法完全正确吗?

2 个答案:

答案 0 :(得分:0)

为什么不使用DelegateCommand或RelayCommand?如果你这样做,你就不必问这个问题,因为只有Comand本身是公开的 - 然后canexecute和execute方法是私有的。

我们只需要对公共事物进行单元测试。

ps:不要错过我对你的问题的评论,直接在你的视图模型中使用IMessageBoxService而不是MessageBox。

答案 1 :(得分:0)

在某些情况下,测试命令可能是另一个测试夹具,因为命令背后有逻辑(启用禁用按钮)。如果你只在CanExecute方法上返回true,那么单元测试命令是没有用的,但是当你的disable-enable按钮包含一个复杂的逻辑时,你应该在不同的fixture中测试它。

注意(如果不同意则忽略它):

  1. 尝试使用relay command或者将VM传递给。{ 命令,最小化循环引用始终是最佳实践。
  2. 永远不要将不可测试对象引用到VM中(视图 - 包括消息框,具有复杂依赖关系树的大对象等)。