为什么我的Command.CanExecute总是在单元测试中返回false?

时间:2011-04-01 09:11:32

标签: c# wpf unit-testing icommand

我的粘贴命令似乎在正常执行期间有效,但在单元测试中,CanExecute方法始终返回false

代码:

public class ViewModel
{
    public CommandBindingCollection CommandBindings { get; set; }
    public ICommand PasteCommand { get; set; }

    public ViewModel()
    {
        CommandBinding pasteBinding 
            = new CommandBinding(ApplicationCommands.Paste, Paste, CanPasteExecute);
        RegisterCommandBinding(pasteBinding, typeof(ViewModel));
        PasteCommand = (RoutedUICommand)pasteBinding.Command;
    }

    private void CanPasteExecute(object sender, CanExecuteRoutedEventArgs e)
    {
        e.CanExecute = true;
    }
    private void Paste(object sender, ExecutedRoutedEventArgs e)
    {
        // ...
    }
    private void RegisterCommandBinding(CommandBinding newCommandBinding, Type type)
    {
        if (CommandBindings == null)
            CommandBindings = new CommandBindingCollection();
        CommandManager.RegisterClassCommandBinding(type, newCommandBinding);
        CommandBindings.Add(newCommandBinding);
    }
}

单元测试:

[TestClass]
public class ViewModelTests
{
    private ViewModel _viewModel;

    [TestInitialize]
    public void Initialise()
    {
        _viewModel = new ViewModel();
    }

    [TestMethod]
    public void PasteTest()
    {
        // canExecute is always false somehow
        bool canExecute = _viewModel.PasteCommand.CanExecute(null);
        Assert.AreEqual<bool>(true, canExecute);
    }
}

1 个答案:

答案 0 :(得分:4)

我猜你在某个时候将你的CommandBindings属性绑定到UI控件,并且该命令是从UI触发的?

RoutedCommands这样的{p> ApplicationCommands.Paste依赖于父UI元素上的CommandBinding,高于触发命令的元素。命令的CanExucute请求从调用命令的控件(当前焦点或命令的目标)开始,并向上冒泡,如RoutedEvent寻找匹配的CommandBinding。当它找到一个时,它会从绑定中执行CanExecute委托,以返回您正在寻找的值。

由于测试中没有UI,并且没有命令的目标,因此调用命令CanExecute将无法找到委托,因此将返回false。

所以,我不认为你的当前形式的测试在没有UI存在的情况下会起作用。

(我现在要去测试我的理论 - 稍后会编辑!)