开发者

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

My Paste command seems to work during normal execution, but in unit test the CanExecute method alway开发者_如何学运维s 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);
    }
}


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!)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜