C # wpf UnitTesting viewmodels

1

Я пытаюсь выполнить модульное тестирование своих режимов просмотра в приложении wpf. У меня есть команда в моей модели viewmodel, которая выполняет метод, содержащий диалоговое окно подтверждения. Мне нужно запустить все модульные тесты, так что каждый раз, открывая эти диалоги, требуется ручное подтверждение.

Вопрос, который у меня есть, заключается в том, что я могу программно узнать, у какого метода есть диалоговое окно подтверждения и программным образом нажать "ОК" или "Отменить"?

  • 0
    Какой код вы используете, чтобы показать диалог подтверждения?
Теги:
unit-testing
wpf
mvvm

1 ответ

0

Лучшим решением для этого, вероятно, является попытка не нажимать Ok или Cancel программно, а предотвращать создание диалогов во время выполнения модульных тестов.

Для этого вам нужна абстракция для получения подтверждения пользователя, что-то вроде этого:

public interface IUserConfirmation
{
    bool Confirm(string title, string message);
}

В Execute-методе вашей команды вы используете эту абстракцию, вместо того чтобы фактически показывать диалог:

public class ViewModel 
{
    private void MyCommandExecuted(object parameter)
    {
        if (this.confirmation.Confirm("Please confirm", "Are you sure you want to ...?")
        {
            ...
        }
    }

Теперь вы создаете две реализации этого интерфейса: тот, который на самом деле показывает диалог пользователю, а другой, который просто возвращает предварительно сконфигурированное значение. В вашем основном приложении вы используете "реальную" реализацию диалога, и в ваших модульных тестах вы используете "поддельную" реализацию.

Чтобы сделать это, вы должны иметь возможность "вводить" различные реализации в ViewModel, например, через конструктор:

public ViewModel(IUserConfirmation confirmation)
{
    if (confirmation == null)
        throw new ArgumentNullException("confirmation");

    this.confirmation = confirmation;
}

private readonly IUserConfirmation confirmation;

На самом деле это хорошо известный шаблон, называемый "инъекция зависимостей". Существуют доступные рамки, которые могут помочь вам в создании объектов, но для простых случаев, подобных этому, они не нужны.

Вот как выглядели бы две реализации:

public class MessageBoxUserConfirmation : IUserConfirmation
{
    public bool Confirm(string title, string message)
    {
        return MessageBox.Show(title, message) == true;
    }
}

public class TestUserConfirmation: IUserConfirmation
{
    public bool Result { get; set; }

    public bool Confirm(string title, string message)
    {
        return this.Result;
    }
}

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

var confirmation = new TestConfirmation();
var viewModel = new ViewModel(confirmation);

// simulate a user clicking "Cancel"
confirmation.Result = false;

viewModel.MyCommand.Execute(...);

// verify that nothing happened

Существуют также фреймворки для создания этих поддельных реализаций без необходимости писать свои собственные классы все время, но опять же, для простых случаев, которые вам, вероятно, им не понадобятся.

  • 0
    Большое спасибо за ответ, Даниэль. Я постараюсь поэкспериментировать ваше предложение и сообщу вам о результатах.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню