21

修飾子でマークされた次の非同期xUnit.netテストは、例外がスローされなかったことを報告して失敗します。lambdaasync

    [Theory, AutoWebData]
    public async Task SearchWithNullQueryThrows(
        SearchService sut,
        CancellationToken dummyToken)
    {
        // Fixture setup
        // Exercise system and verify outcome
        Assert.Throws<ArgumentNullException>(async () =>
            await sut.SearchAsync(null, dummyToken));
        // Teardown
    }

ArgumentNullExceptionanが実際にスローされることを確認するために、明示的にtry-catchブロックを使用しました。うまくいきましたが、結果のコードはクリーンではありません (最初のテストと比較して):

[Theory, AutoWebData]
public async Task SearchWithNullQueryThrows(
    SearchService sut,
    CancellationToken dummyToken)
{
    // Fixture setup
    var expected = typeof(ArgumentNullException);
    Type actual = null;
    // Exercise system
    try
    {
        await sut.SearchAsync(null, dummyToken);
    }
    catch (ArgumentNullException e)
    {
        actual = e.GetType();
    }
    // Verify outcome
    Assert.Equal(expected, actual);
    // Teardown
}

修飾子でマークされた が失敗Assert.Throws<T>するのはlambdaなぜですか?async

4

2 に答える 2

39

アップデート

これはxUnit2で解決され、。が追加されましたAssert.ThrowsAsync


私はそれが認識されていないのでAssert.Throwsはないかと疑っていasyncます。xUnitチームでこの問題を提起し、追加することを提案するThrowsAsyncことをお勧めします。

この場合のデリゲートはまたはをasync返しますが、デリゲートから直接スローされることはありません。代わりに、()に配置されます。は、戻り値のプロパティに配置されるのではなく、デリゲートから直接例外がスローされることを期待しています。TaskTask<T>ArgumentNullExceptionTaskTask.Exception.InnerExceptionAssert.Throws

あなたはそのようにあなた自身AssertEx.ThrowsAsyncを作成することができます:

public static async Task ThrowsAsync<TException>(Func<Task> func)
{
  var expected = typeof(TException);
  Type actual = null;
  try
  {
    await func();
  }
  catch (Exception e)
  {
    actual = e.GetType();
  }
  Assert.Equal(expected, actual);
}

そのように使用することができます:

[Theory, AutoWebData]
public async Task SearchWithNullQueryThrows(
    SearchService sut,
    CancellationToken dummyToken)
{
    // Fixture setup
    // Exercise system and verify outcome
    await AssertEx.ThrowsAsync<ArgumentNullException>(async () =>
        await sut.SearchAsync(null, dummyToken));
    // Teardown
}

私はMSTestでも同様のアプローチを使用しています。

于 2012-12-31T16:35:20.940 に答える
3

例外を返して検証する必要がある場合は、次のようにすると便利です。

public static async Task<Exception> AssertThrowsAsync<TException>(Func<Task> func)
    {
        var expected = typeof (TException);
        Exception exception = null;
        Type actual = null;
        try
        {
            await func();
        }
        catch (Exception e)
        {
            actual = e.GetType();
            exception = e;
        }
        Assert.NotNull(exception);
        Assert.Equal(expected, actual);
        return exception;
    }
于 2015-11-25T09:22:23.147 に答える