简体   繁体   中英

Strange behavior of NUnit async test with delegate

I ran into a strange behavior of NUnit tests with async delegates.

MyAsyncTest , where I declare the delegate beforehand, fails with System.ArgumentException : Async void methods are not supported. Please use 'async Task' instead. System.ArgumentException : Async void methods are not supported. Please use 'async Task' instead.

MyAsyncTest2 , where I paste delegate right in, passes.

[Test] //fails
public void MyAsyncTest()
{
       TestDelegate testDelegate = async () => await MyTestMethod();

       Assert.That(testDelegate, Throws.Exception);
}

[Test] //passes
public void MyAsyncTest2()
{
       Assert.That(async () => await MyTestMethod(), Throws.Exception);
}

private async Task MyTestMethod()
{
       await Task.Run(() => throw new Exception());
}

Can someone explain?

The problem here is in async void callbacks.

Since 'MyAsyncTest1' uses TestDelegate and it returns void(it becomes async void), it can't handle Exception properly.

If you pay attention in 'MyAsyncTest2' test the type of argument is ActualValueDelegate with Task return type (meaning the Exception will be handled correctly).

To fix the issue you have to explicitly specify the return type to be Task. See provided example.

    public class Tests
    {
        [Test]
        public void MyAsyncTest()
        {
            Func<Task> testDelegate = async () => await MyTestMethod();

            Assert.That(testDelegate, Throws.Exception);
        }

        private async Task MyTestMethod()
        {
            await Task.Run(() => throw new Exception());
        }
    } 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM