web-dev-qa-db-ja.com

NUnit3:非同期タスクでAssert.Throws

テストをNUnit3に移植しようとしていますが、System.ArgumentExceptionが発生します。「async void」メソッドはサポートされていません。代わりに「async Task」を使用してください。

[Test]
public void InvalidUsername()
{
...
var exception = Assert.Throws<HttpResponseException>(async () => await client.LoginAsync("[email protected]", testpassword));
exception.HttpResponseMessage.StatusCode.ShouldEqual(HttpStatusCode.BadRequest); // according to http://tools.ietf.org/html/rfc6749#section-5.2
...
}

Assert.Throwsは、次のように定義されたTestDelegateを取得するように見えます。

public delegate void TestDelegate();

したがって、ArgumentException。このコードを移植する最良の方法は何ですか?

33
tikinoa

これはNunitによって解決されました。 Assert.ThrowsAsync <>()を使用できるようになりました

https://github.com/nunit/nunit/issues/119

例:

Assert.ThrowsAsync<Exception>(() => YourAsyncMethod());
49
Zabbu

読みやすくするため、Assert.ThrowsAsyncではなく次のコードをお勧めします。

// Option A
[Test]
public void YourAsyncMethod_Throws_YourException_A()
{
    // Act
    AsyncTestDelegate act = () => YourAsyncMethod();

    // Assert
    Assert.That(act, Throws.TypeOf<YourException>());
}

// Option B (local function)
[Test]
public void YourAsyncMethod_Throws_YourException_B()
{
    // Act
    Task Act() => YourAsyncMethod();

    // Assert
    Assert.That(Act, Throws.TypeOf<YourException>());
}
5
arni

例外が確実にスローされるようにするには、catchブロックでアサートしないことをお勧めします。このようにすると、正しい参照タイプが確実にスローされます。そうしないと、null参照またはキャッチされない別の例外が発生するためです。

HttpResponseException expectedException = null;
try
{
    await  client.LoginAsync("[email protected]", testpassword));         
}
catch (HttpResponseException ex)
{
    expectedException = ex;
}

Assert.AreEqual(HttpStatusCode.NoContent, expectedException.Response.BadRequest);
1
BrianPMorin

結局、NUnitの機能を反映した静的関数を作成してしまいました。これについて https://github.com/nunit/nunit/issues/464 で会話全体がありました。

public static async Task<T> Throws<T>(Func<Task> code) where T : Exception
{
    var actual = default(T);

    try
    {
        await code();
        Assert.Fail($"Expected exception of type: {typeof (T)}");
    }
    catch (T rex)
    {
        actual = rex;
    }
    catch (Exception ex)
    {
        Assert.Fail($"Expected exception of type: {typeof(T)} but was {ex.GetType()} instead");
    }

    return actual;
}

次に、私のテストから次のように使用できます

var ex = await CustomAsserts.Throws<HttpResponseException>(async () => await client.DoThings());
Assert.IsTrue(ex.Response.StatusCode == HttpStatusCode.BadRequest);
0
Eric