как проверить мне нужно попробовать поймать

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

public class StudentPresenter
{
    IView myview;
    Repository myrepo;
    public StudentPresenter(IView vw, Data.Repository rep)
    {
        this.myview = vw;
        this.myrepo = rep;
        this.myview.ButtonClick += myview_ButtonClick;
    }

    public void myview_ButtonClick()
    {
        try
        {
         var d = this.myrepo.GetById(int.Parse(myview.GivenId));
         this.myview.GetStudent(d);
        }
        catch(Exception e)
        {
        }

    }
}


Мне нужно протестировать myview_ButonClick()
Предположим, я протестирую этот метод, и он выдаст исключение, если myview.GivenId имеет значение null?
Итак, я пишу модульный тест, как показано ниже:

[Test]       
public void Button1Click_NullText_ThrowException()
{
    var mock = Substitute.For<IView>();
    StudentPresenter sp = new StudentPresenter(mock, repo);
    mock.GivenId = string.Empty;
    Assert.Throws<Exception>(()=>sp.myview_ButtonClick());
}


Но тест не удался .. Почему? (потому что в моем блоке улова нет броска). Но я не хочу ничего бросать, я просто хочу, чтобы у него была способность ловить. Так можно ли протестировать?


person Michael Riva    schedule 30.04.2014    source источник
comment
Вышеупомянутый вопрос по сути тот же, что и ваш: вам не нужно проверять, что часть вашего устройства работает должным образом, вы должны тестировать устройство целиком. Обратите внимание, что ловить исключение (и определенно общее Exception) и ничего не делать - это плохая практика.   -  person Jeroen Vannevel    schedule 30.04.2014
comment
@JeroenVannevel спасибо за ссылку   -  person Michael Riva    schedule 30.04.2014


Ответы (2)


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

У NUnit есть утверждение DoesNotThrow, которое может быть здесь полезно.

Конечно, это не гарантия существования попытки / улова, но это лучшее, что вы можете сделать.

person BradleyDotNET    schedule 30.04.2014
comment
+1. Обратите внимание, что если кто-то действительно хочет проверить наличие _1 _ / _ 2_ в методе, можно получить IL метода и проанализировать его ... но было бы действительно сложно называть его модульным тестом в этой точке. - person Alexei Levenkov; 30.04.2014
comment
@AlexeiLevenkov: с Roslyn это было бы отчасти возможно (на самом деле, это было бы довольно просто), но это было бы довольно грязно. И действительно бесполезно - person Jeroen Vannevel; 30.04.2014
comment
@AlexeiLevenkov звучит хорошо, вы можете привести пример? это будет ужасно, если вы это сделаете. - person Michael Riva; 30.04.2014
comment
@AlexeiLevenkov, мне даже не приходилось проверять IL, как вы говорите, это не совсем unit тест. На самом деле, я не совсем уверен, что это за тест. Возможно, вы изобрели новый! - person BradleyDotNET; 30.04.2014
comment
@AlexeiLevenkov да, пожалуйста, мне действительно интересно, мне нужен пример :) - person Michael Riva; 30.04.2014
comment
@MichaelRiva Я не уверен, что вы понимаете концепцию unit теста. Модульные тесты проверяют, что функция ведет себя должным образом при различных входных данных / состояниях. Вы не должны проверять конкретную строку кода (или ключевое слово), вы должны проверять правильность поведения. Для модульного теста функция - это черный ящик, и все, что имеет значение, - это правильный вывод при определенных входных данных. Я уверен, что посмотреть код IL было бы интересно, но вы должны понимать, что вы не должны делать этого. - person BradleyDotNET; 30.04.2014
comment
@MichaelRiva - один из вариантов - посмотреть на ILSpy для вдохновения. Чтобы получить чистый IL (байты) - MethodInfo.GetMethodBody - person Alexei Levenkov; 30.04.2014
comment
@BradleyDotNET - это именно то, что делает анализ кода в VS, а не тест. Это может быть полезно для какой-то автоматической проверки стороннего кода, т.е. для проверки использования (или неиспользования) определенного API - может быть по адресу прием тестов .. - person Alexei Levenkov; 30.04.2014

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

Если вы хотите перехватить исключение, сделать что-нибудь с ним, а затем выбросить его, чтобы вызывающий абонент перехватил его или тест прошел, тогда просто

catch (Exception e)
{
    //actions....
    throw;
}

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

person barrick    schedule 30.04.2014