Почему мой Command.CanExecute всегда возвращает false в модульном тесте? - PullRequest
2 голосов
/ 01 апреля 2011

Команда My Paste работает во время обычного выполнения, но в модульном тесте метод 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 Ответ

4 голосов
/ 01 апреля 2011

Я предполагаю, что в какой-то момент вы связываете свое свойство CommandBindings с элементом управления пользовательского интерфейса и что команда запускается из пользовательского интерфейса?

RoutedCommands подобно ApplicationCommands.Paste полагается на наличие CommandBinding в родительском элементе пользовательского интерфейса, над которым запускается команда. Запрос CanExucute команды начинается с элемента управления, на котором она вызывается (текущий фокус или цель команды), и всплывает вверх, как RoutedEvent, в поисках соответствующего CommandBinding. Когда он находит его, он выполняет делегат CanExecute из привязки, чтобы вернуть искомое значение.

Поскольку в вашем тесте нет пользовательского интерфейса и нет цели для команды, вызов CanExecute команды просто не найдет делегата и, следовательно, вернет false.

Итак, я не думаю, что ваш тест в его текущей форме будет работать без присутствия пользовательского интерфейса.

(сейчас я собираюсь проверить свою теорию - позже отредактирую!)

...