2

我的粘贴命令似乎在正常执行期间工作,但在单元测试中该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);
    }
}
4

1 回答 1

4

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

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

因为您的测试中没有 UI,也没有命令的目标,所以调用命令CanExecute将根本找不到委托,因此将返回 false。

所以,我认为如果没有 UI 存在,您的当前形式的测试将无法工作。

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

于 2011-04-01T09:37:52.163 回答