Why does my Command.CanExecute always return false in unit test?

。_饼干妹妹 提交于 2019-12-12 20:46:06

问题


My Paste command seems to work during normal execution, but in unit test the CanExecute method always returns false.

Code:

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);
    }
}

Unit test:

[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:


I'm guessing that you bind your CommandBindings property to a UI control at some point, and that the command is fired from the UI?

RoutedCommands like ApplicationCommands.Paste rely on there being a CommandBinding at a parent UI element, above that which the command is fired on. The command's CanExucute request starts at the control on which the command is invoked (either the current focus or the command's target), and bubbles upward like a RoutedEvent looking for a matching CommandBinding. When it finds one, it executes the CanExecute delegate from the binding to return the value you're looking for.

Because there's no UI in your test, and no target for the command, calling the command's CanExecute will simply not find a delegate and will thus return false.

So, I don't think your test in its current form would work without the UI being present.

(I'm going to go test my theory now - will edit later!)



来源:https://stackoverflow.com/questions/5511327/why-does-my-command-canexecute-always-return-false-in-unit-test

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!