14

どの例外がスローされるかを気にしない場合があります (何らかの例外がスローされる限り)。不運にも、

Assert.Throws<Exception>(someDelegate);

Exceptionのインスタンス(派生クラスのインスタンスではない) がスローされない限り、合格しません。私は私が望む行動を得ることができることを知っています

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

しかし、それは正しく読みません。必要な動作をする xUnit に欠けているものはありますか? 私が言いたいことを示す2つのテストを次に示します。

[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(); }
    );
}
4

6 に答える 6

8

ここのドキュメントによると:

http://xunit.codeplex.com/wikipage?title=HowToUse&referringTitle=ホーム

スローする例外のタイプを指定する必要があります。一般に、これは良い方法です。テストでどのようなシナリオがスローされ、どのような種類の例外がスローされるかを予測できる必要があります。これを予測できるように、メソッドとテストの両方を設計できる必要があります。

これを回避するには、自分で try catch を実行するなどの方法がありますが、デザインを少し変更することを検討する必要があります。

于 2010-12-15T14:55:35.180 に答える
5

この質問の時点では存在しませんでしたが、Assert.ThrowsAny<Exception>派生元の例外をテストするExceptionなどのバリアントとともに、派生元の例外 (したがって、すべての例外)Assert.ThrowsAny<ArgumentException>をテストするために使用できますArgumentException

于 2015-09-08T23:54:43.400 に答える
2

Assert.Throws<T>法案に合わないかどうかを特定したように、残っている xUnit の唯一の OOTB は を使用することですRecord.Exception

あなたが特定したように、「Assert throws anything」を行う主な方法は、

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です。

于 2013-07-20T07:50:25.393 に答える
2

次のような独自のCustom Assertionを実行する場合、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;
}
于 2010-12-15T15:00:33.107 に答える
1

私は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))

パッチを提出することを提案できますか?

于 2013-08-19T15:20:15.720 に答える
0
    public static void SuppressException<TSut>(this TSut value, Action<TSut> action) where TSut : class
    {
        try
        {
            action.Invoke(value);
        }
        catch (Exception)
        {
            //do nothing
        }
    }
于 2016-01-20T04:16:06.690 に答える