58

我正在尝试将测试移植到 NUnit3 并收到 System.ArgumentException:不支持“async void”方法,请改用“async Task”。

[Test]
public void InvalidUsername()
{
    ...
    var exception = Assert.Throws<HttpResponseException>(async () => await client.LoginAsync("notarealuser@example.com", 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。移植此代码的最佳方法是什么?

4

5 回答 5

99

Nunit 解决了这个问题。您现在可以使用 Assert.ThrowsAsync<>()

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

例子:

Assert.ThrowsAsync<Exception>(() => YourAsyncMethod());
于 2016-03-18T12:43:04.193 回答
12

我建议使用以下代码而不是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>());
}
于 2017-01-18T15:04:59.517 回答
0

为了确保抛出异常,如果您选择使用一个,最好不要在 catch 块中断言。这样,您可以确保抛出正确的异常类型,否则您将获得空引用或未捕获的不同异常。

HttpResponseException expectedException = null;
try
{
    await  client.LoginAsync("notarealuser@example.com", testpassword));         
}
catch (HttpResponseException ex)
{
    expectedException = ex;
}

Assert.AreEqual(HttpStatusCode.NoContent, expectedException.Response.BadRequest);
于 2016-02-04T17:38:31.830 回答
0

我最终编写了一个反映 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);
于 2016-02-16T21:42:25.957 回答
-4

你可以尝试使用这样的东西:

 try
 {
     await client.LoginAsync("notarealuser@example.com", testpassword);
 }
 catch (Exception ex)
 {
     Assert.That(ex, Is.InstanceOf(typeof (HttpResponseException)));
 }
于 2015-11-23T22:01:42.937 回答