2013-08-12 1 views
3

У меня есть класс (для простоты я буду называть его MyCustomCommand), который в основном принимает двух делегатов для выполнения и CanExecute. Этот класс реализует ICommand. Это позволяет мне объявить свойство в моей модели, с которой я связываюсь с XAML.Единичное тестирование с помощью Mock, когда viewmodel содержит ICommand

Проблема заключается в том, что я столкнулся с сценарием, когда мне нужно выполнить Mock модель представления из-за зависимости в одной из моих команд под названием ApplyChangesCommand. Я не уверен, что зависимость еще хуже. На данный момент это относительно необходимо.

Из-за этой зависимости я использую Mock Setups для создания обратного вызова, который в основном «ничего не делает», чтобы обойти зависимость.

Теперь, когда у меня была модель Mock'd, все свойства экземпляра, конечно, теперь равны нулю. Это включает в себя мои команды.

Простой пример был бы:

private void _somethingToExecute; 
public ICommand ApplyChangesCommand { get { return MyCustomCommand(_somethingToExecute, e=>true); } 

Есть ли способ, с Мок, что я могу на самом деле вызвать _somethingToExecute ApplyChangesCommand в? Callbase не режет его, и я не могу придумать другого способа сделать это.

Обходным способом является создание «_somethingToExecute» и создание ApplyChangesCommand в моем тесте, но я не поклонник.

Любые советы, оцененные.

Благодаря

+0

Мне пришлось прочесть его пару раз, чтобы попытаться понять, о чем вы спрашиваете, поэтому я могу быть здесь. У вас есть проблемы с модулем тестирования команды или ViewModel, содержащим команду?Если команда (это то, о чем я думаю, вы спрашиваете), не можете ли вы просто высмеять входящего делегата в конструктор 'MyCustomCommand' и просто проверить, вызван ли делегированный делегат? Это будет правильный единичный тест для команды. Тестирование ViewModel было бы аналогичным - высмеивать команду и вызывать вызов 'Execute'' _somethingToExecute'. – Gjeltema

+0

Большое спасибо за предложение. Позвольте мне понять, что ... похоже, что это может быть на правильном пути! Моя проблема действительно вращается вокруг единицы, проверяющей команду, потому что я макет модели просмотра. Поскольку модель View mock'ed сама команда имеет значение null – tronious

ответ

1

Хорошо, теперь, когда у меня было больше времени, чтобы смотреть на это не перебрасывались на работе, я вижу проблему. Что вы должны сделать, это использовать завод по заказу, чтобы создать ApplyChangesCommand. Затем для модульного тестирования вашей виртуальной машины вы просто убедитесь, что команда возвращает созданную фабрикой команду. Ниже приведен пример:

public class MyViewModel 
{ 
    private MyCustomCommandFactory _commandFactory; 
    private void _somethingToExecute; 

    public MyViewModel(MyCustomCommandFactory commandFactory) 
    { 
     _commandFactory = commandFactory; 
    } 

    public ICommand ApplyChangesCommand 
    { 
     get 
     { 
      return _commandFactory.Create(_somethingToExecute, e=>true); 
     } 
    } 
} 

Это предполагает, что вы желая создать новую команду каждый раз, когда прибудете называется (который, кажется, как вы его настроить). Если вам нужна только одна команда, созданная для жизни виртуальной машины, вы можете просто создать команду через фабрику в конструкторе виртуальной машины.

Для модульного тестирования этого, вы можете сделать что-то вроде этого:

[Test] 
public void ApplyChangesCommand_Always_ReturnsFactoryCreatedCommand 
{ 
    Mock<ICommand> mockCreatedCustomCommand = new Mock<ICommand>(); 
    Mock<MyCustomCommandFactory> mockCommandFactory = new Mock<MyCustomCommandFactory>(); 
    mockCreatedCustomCommand.Setup(p => p.Create(It.IsAny<Action>(), e => true)) 
          .Returns(mockCreatedCustomCommand.Object); 
    Assert.That(systemUnderTest.ApplyChangesCommand, Is.SameAs(mockCreatedCustomCommand.Object)); 
} 

(Изменить Action за то, что ваш делегат на самом деле).

Это все, что вам нужно для модульного тестирования команды VM. Если вы хотите проверить, что поведение - это то, что вы ожидаете (это означает, что он выполняет переданный в делегате и возвращает ожидаемое значение с использованием этого делегата), тогда это область приемочных тестов.

Примечание: В моем примере тестирования я использовал синтаксис фреймов Moq mocking.

Лично я бы так не передавал делегатам Command. Я бы вместо этого применил все то, что нужно Command, и имеет всю логику внутри Command, где он легче тестируется на модуле и имеет более слабую зависимость от виртуальной машины.

Смежные вопросы