Команды и методы модульного тестирования - PullRequest
0 голосов
/ 26 мая 2020

Я разработал приложение WPF с использованием MVVM в качестве архитектуры и пишу несколько модульных тестов как часть этого. На мой взгляд, у меня есть кнопка, привязанная к свойству в ViewModel, которое можно увидеть ниже.

ViewModel

public ICommand MoreInfoCommand
{
    get
    {
        if (_moreInfoCommand == null) 
        {
             _moreInfoCommand = new RelayCommand(parameter => OpenLink());
        }
        return _moreInfoCommand;
    }
}

private void OpenLink() 
{
    try 
    {
         Process.Start("https://www.google.com/");
    }
    catch
    {
      // catch error...
    }
}

В моем модульном тестировании я создал следующий модульный тест:

UnitTest

[Description("Test MoreInfoCommand")]
[TestMethod]
public void TestMoreInfoCommand() 
{
     viewModel vm = new viewModel();
     Assert.IsTrue(vm.MoreInfoCommand.CanExecute(null));
}

В настоящее время это тестирует свойство, чтобы увидеть, может ли быть выполнен соответствующий метод при нажатии кнопки в пользовательском интерфейсе. Это проходит по мере выполнения условий, однако, насколько я понимаю, мне также нужно проверить функциональность. Имея это в виду, как мне, например, проверить, что при нажатии кнопки происходит правильная работа. Т.е. как проверить, что происходит, когда ICommand MoreInfoCommand выполняется в результате нажатия кнопки в пользовательском интерфейсе.

Я знаю, что частные методы можно тестировать напрямую, но при модульном тестировании я должен также проверять функциональность, и если да, то как я могу это сделать.

Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 26 мая 2020

Ваша модель представления на самом деле не поддается тестированию. Если вы хотите, чтобы это было, вы должны заменить вызов метода stati c Process.Start на вызов метода интерфейса, который вы вводите в модель представления:

public ViewModel(IProcessLoader processLoader) =>
    _processLoader = processLoader;

//...

private void OpenLink()
{
    try
    {
        _processLoader.Start("https://www.google.com/");
    }
    catch
    {
        // catch error...
    }
}

You затем можно имитировать интерфейс в своем модульном тесте, например, используя фреймворк типа Moq :

[TestMethod]
public void TestMoreInfoCommand()
{
    //Arrange
    Mock<IProcessLoader> processLoader = new Mock<IProcessLoader>();
    viewModel vm = new viewModel(processLoader.Object);
    ICommand command = vm.MoreInfoCommand;

    //Act
    command.Execute(null);

    //Assert
    processLoader.Verify(x => x.Start(It.IsAny<string>()));
}

В реальном приложении вы должны реализовать интерфейс как оболочку вокруг Process.Start:

public interface IProcessLoader
{
    void Start(string s);
}

public class ProcessLoader : IProcessLoader
{
    public void Start(string s) => Process.Start(s);
}

Важно понимать, что вы должны проверять только то, что метод вызывается из модели представления. Модульный тест класса модели представления не должен проверять функциональность класса Process. Ответственность модели представления заканчивается после вызова Start.

. NET и соответствующая ОС отвечает за то, что на самом деле делает класс Process. Вы не должны тестировать это, а только свой собственный код.

0 голосов
/ 26 мая 2020

vm.MoreInfoCommand.CanExecute(null) вызовет только метод canExecute в вашем RelayCommand, но вы его не предоставили. CanExecute ничего не говорит о том, будет ли OpenLink работать успешно или нет.

Хотя я не специалист по модульным тестам, если ваш код действительно выглядит так, я сомневаюсь, стоит ли писать для него модульный тест во-первых, потому что это очень просто.

Как указано в комментарии пользователя auburg, вы можете проверить, запускается ли процесс, хотя имя процесса будет зависеть от того, какой браузер был стандартным браузером. Кроме того, вам придется подождать некоторое время, чтобы процесс начался. И, возможно, уже был запущен процесс с таким же именем, много шансов на проблемы.

Если вы действительно хотите, вы можете проверить, является ли один из хорошо известных фреймворков для имитации, например Moq или Rhino Mocks, возможность издеваться над Process.Start.

...