Модульное тестирование просмотра моделей с помощью RelayCommands

1

У меня проблема с моими модульными тестами модели представления. Я бы хотел проверить свой код следующим образом:

[Test]
public void SelectCommand_ExecutedWithNull_Throws()
{
    // * Arrange
    var fixture = new Fixture();
    var sut = fixture.Build();

    // * Act & Assert
    Assert.Throws<ArgumentNullException>(() => sut.SelectCommand.Execute(null));
}

Действие, выполняемое командой:

private async void Select(IInsuranceCh insurance)
{
    if (insurance == null)
        throw new ArgumentNullException("insurance");

    try
    {
        /* ... */
    }
    catch (Exception err)
    {
        _childWindowService.ShowLoadingErrorWindow(err);
    }
    finally
    {
        IsBusy = false;
    }
}

Как я подключаю команду:

SelectCommand = new RelayCommand<IInsuranceCh>(Select);

Однако, когда я пытаюсь это сделать, тест терпит неудачу, хотя исключение бросается и не попадает в мой код. Когда я пытаюсь поймать вокруг sut.SelectCommand.Execute(null); , блок catch не вводится. Это заставляет меня поверить, что RelayCommand (из MVVM-Light Toolkit) поглощает исключение. Как я могу это предотвратить?

EDIT: некоторые уточнения и Assert.Throws

EDIT2: Добавлено действие и подключение к команде. Может быть, асинк играет роль?

  • 0
    Не ответ на ваш вопрос, но не используйте атрибут ExpectedException . Вместо этого используйте Assert.Throws или Assert.That(code, Throws.ArgumentNullException) . Потому что тест, который использует ExpectedException может быть ложноположительным. Он может пройти тест, даже если ваша фаза настройки прибора выдает исключение, а не фазу действия.
  • 0
    Вы используете свой RelayCommand или от 3rdParty?
Показать ещё 2 комментария
Теги:
nunit
mvvm-light

1 ответ

1

Причина в том, что RelayCommand использует отражение для вызова динамического метода. Отражение будет охватывать исключение действия как внутреннее исключение.

When created, the TargetInvocationException is passed a reference to the exception thrown by the method invoked through reflection. The InnerException property holds the underlying exception.
https://msdn.microsoft.com/en-us/library/system.reflection.targetinvocationexception(v=vs.110).aspx

Если вы хотите поймать исключение из внешней библиотеки. вы должны отключить "Только мой код" в настройках отладчика. (NUnit: Почему не Assert.Throws <T> Поймать мое аргументNullException?)

  • 0
    На самом деле, я хочу бросить исключение. Я хочу проверить, что исключение ArgumentNull в моем коде выбрасывается. Самое смешное, что мой код на самом деле исполняется. И исключение выдается (проверено с помощью отладчика). Но исключение проглатывается. Я не вижу никакой попытки поймать в исходном коде MVVM-Light, хотя. Вот почему я в замешательстве.
  • 0
    Соответствующий источник находится здесь: mvvmlight.codeplex.com/SourceControl/latest#GalaSoft.MvvmLight/…
Показать ещё 9 комментариев

Ещё вопросы

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