Игнорирование исключений в xUnit.net - PullRequest
13 голосов
/ 13 декабря 2010

У меня есть несколько случаев, когда мне все равно, какое исключение выдается (если выброшено какое-то исключение) К сожалению,

Assert.Throws<Exception>(someDelegate);

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

Exception exception = Record.Exception(someDelegate);
Assert.NotNull(exception);

но он не читается правильно. Я что-то упустил в xUnit, который имеет поведение, которое я хочу? Вот два теста, которые показывают, что я имею в виду:

[Fact]
public void Throws_exception_and_passes() {
    Exception exception = Record.Exception(
        () => { throw new InvalidOperationException(); }
    );
    Assert.NotNull(exception);
}

[Fact]
public void Throws_exception_and_fails() {
    Assert.Throws<Exception>(
        () => { throw new InvalidOperationException(); }
    );
}

Ответы [ 6 ]

7 голосов
/ 15 декабря 2010

Согласно документации здесь:

http://xunit.codeplex.com/wikipage?title=HowToUse&referringTitle=Home

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

Есть способы обойти это, например попытаться поймать себя, но вы должны немного изменить свой дизайн.

5 голосов
/ 09 сентября 2015

На момент этого вопроса его не было, но теперь можно использовать Assert.ThrowsAny<Exception> для проверки любого исключения, полученного из Exception (и, следовательно, любого исключения вообще), наряду с вариантами, такими как Assert.ThrowsAny<ArgumentException>который будет проверять любое исключение, полученное из ArgumentException и т. д.

2 голосов
/ 20 июля 2013

Как вы определили, если Assert.Throws<T> не соответствует требованиям, единственная вещь OOTB в xUnit, с которой вы остаетесь, это использование Record.Exception.

Как вы определили, основной способ сделать "Assert бросает что-нибудь" - это сделать

Assert.NotNull( Record.Exception( lambda ))

Посмотри на это - не красиво. Это вероятно по замыслу; В xUnit.net очень мало вещей, которые случайно (в отличие от тщательно продуманного и продуманного дизайна).

Record.Exception возвращает результат по причине (и если бы вы использовали F #, вам пришлось бы |> ignore, чтобы убрать значение). Вы всегда должны быть в состоянии Assert что-то сказать о природе исключения, которое происходит , чтобы реальная проблема в вашем коде не была случайно проигнорирована, если вы со временем изменили свой код, что является причиной для всех это тестирование в первую очередь . Возможно, это может принять форму

var exception = Record.Exception( sut.Something );
Assert.True( typeof(SomeException).IsAssignableFrom( exception ) );

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


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

2 голосов
/ 15 декабря 2010

xUnit не встанет у вас на пути, если вы хотите сделать свое собственное Настраиваемое утверждение , что-то вроде:

public static bool Throws<T>(this Action action, bool discardExceptions = false) 
    where T : Exception
{
    try
    {
        action.Invoke();
    }
    catch (T)
    {
        return true;
    }
    catch (Exception)
    {
        if (discardExceptions)
        {
            return false;
        }
        throw;
    }
    return false;
}

Или:

public static bool Throws(this Action action)
{
    try
    {
        action.Invoke();
    }
    catch (Exception)
    {
       return true;
    }
    return false;
}
1 голос
/ 19 августа 2013

Я просто искал в источнике xUnit.net и вот виновник:

private static Exception Throws(Type exceptionType, Exception exception)
{
    Guard.ArgumentNotNull("exceptionType", exceptionType);

    if (exception == null)
        throw new ThrowsException(exceptionType);

    if (!exceptionType.Equals(exception.GetType()))
        throw new ThrowsException(exceptionType, exception);

    return exception;
}

Что бы решить вашу проблему, если бы это изменение было применено:

if(!exceptionType.Equals(exception.GetType()))

до:

if(!exception.GetType().IsAssignableTo(exceptionType))

Возможно, вы предложите отправить патч?

0 голосов
/ 20 января 2016
    public static void SuppressException<TSut>(this TSut value, Action<TSut> action) where TSut : class
    {
        try
        {
            action.Invoke(value);
        }
        catch (Exception)
        {
            //do nothing
        }
    }
...