Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Advantage of async/await over blocking in unit tests

Modern unit tests frameworks support awaiting the results of an asychronous unit test, like this:

public async Task SomeTest()
{
    var result = await SomeMethodAsync();
    // ... Verify the result ...
}

Is there any advantage of using this async approach over simply blocking?

public void SomeTest()
{
    var result = SomeMethodAsync().Result;
    // ... Verify the result ...
}

Does the async only provide a benefit when running tests in parallel?

like image 995
Edward Brey Avatar asked Nov 02 '15 11:11

Edward Brey


People also ask

What is the advantage of async await advantages?

The main benefits of asynchronous programming using async / await include the following: Increase the performance and responsiveness of your application, particularly when you have long-running operations that do not require to block the execution.

Should unit tests be async?

Moreover, support for async void unit tests varies across frameworks, and even framework versions. For these reasons, it's best to avoid async void unit tests.

When should you use async await?

Async/Await makes it easier to write promises. The keyword 'async' before a function makes the function return a promise, always. And the keyword await is used inside async functions, which makes the program wait until the Promise resolves.

What is the point of await async?

Note: The purpose of async / await is to simplify the syntax necessary to consume promise-based APIs. The behavior of async / await is similar to combining generators and promises. Async functions always return a promise.


2 Answers

The primary benefits of async code are a responsive UI on the client side, and scalability on the server side. For unit tests, you get a bit of scalability (which translates to overall speed benefits since unit tests are bursted by nature).

But it's not a huge benefit. Your tests would (probably) run a bit faster.

I usually use async Task unit test methods for these reasons:

  • If you're testing code within a context, then blocking can cause the classic deadlock problem. Note that some frameworks (e.g., xUnit) always provide a context by default. Even for other frameworks, it's often necessary to provide a context to unit test ViewModels.
  • await doesn't wrap exceptions in AggregateException.
  • You do get a bit of a scalability benefit which (in theory) allows your unit tests to run faster overall. Assuming your framework runs your tests in parallel.
  • Why not? They're just as easy as synchronous methods. async Task unit tests methods have been supported by every major unit test framework since 2012.
like image 113
Stephen Cleary Avatar answered Sep 23 '22 16:09

Stephen Cleary


Is there any advantage of using this async approach over simply blocking?

I think that really depends on what you're testing. If you look at it from the unit test frameworks point of view, then I don't see any benefit here. I don't think such a framework needs to scale with respect to IO. The only thing that you are doing is testing how your async API's behave. For example, as a library author, you could have an async endpoint and test what happens when your code is synchronously blocked by a caller which doesn't understand how to consume your library properly.

One example could be:

[TestClass]
public class M
{
    [TestMethod]
    public void X()
    {
        var myService = new MyService();
        myService.FetchSomeDataAsync().Result; // Will this deadlock?
    }
}
like image 37
Yuval Itzchakov Avatar answered Sep 24 '22 16:09

Yuval Itzchakov