Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NUnit3: Assert.Throws with async Task

I am trying to port a test to NUnit3 and am getting a System.ArgumentException : 'async void' methods are not supported, please use 'async Task' instead.

[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 appears to take a TestDelegate, defined as:

public delegate void TestDelegate();

hence the ArgumentException. What is the best way to port this code?

like image 255
tikinoa Avatar asked Oct 19 '22 15:10

tikinoa


3 Answers

This was resolved by Nunit. You can now use Assert.ThrowsAsync<>()

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

Example:

Assert.ThrowsAsync<Exception>(() => YourAsyncMethod());
like image 107
Zabbu Avatar answered Oct 24 '22 09:10

Zabbu


I would recommend the following code instead of Assert.ThrowsAsync, as this is more readable:

// 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>());
}
like image 12
arni Avatar answered Oct 24 '22 08:10

arni


I ended up writing a static function that mirrors what NUnit does. There was a whole conversation at https://github.com/nunit/nunit/issues/464 about this.

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;
}

Then from my tests I can use it such as

var ex = await CustomAsserts.Throws<HttpResponseException>(async () => await client.DoThings());
Assert.IsTrue(ex.Response.StatusCode == HttpStatusCode.BadRequest);
like image 1
Eric Avatar answered Oct 24 '22 09:10

Eric