The Void – That’s where your test results have gone
Recently, I have been writing integration tests that cover async functions. During this work, I have encountered a quirky pain (of my own making) that I wanted to document. The purpose of the documentation is two-fold. First, the shame and self-deprecation of calling myself out will help to reinforce this point in my mind, and second, you might be able to avoid this goof up yourself.
The spoiler and 5 second take-away: When writing any function that uses async in C#, you must NEVER return
async keyword means that you intend to return something upon which the caller will await. That’s it. Lesson over.
If you want to know how weird things can get if you do this wrong in integration testing, read on…
So, I wrote a function that asynchronously returns a
string. Something like this:
public class Foo
public async Task GetAStringFromIO()
return await GetTheString();
private static Task GetTheString()
return Task.Run(() =>
return "A String";
…and to test that, I wrote something along these lines:
public class MyTests
public async void CanGetTheStringFromIO()
var foo = new Foo();
string myString = null;
myString = await foo.GetAStringFromIO();
To my annoyance and great dismay, the test didn’t seem to run and my breakpoint wasn’t hit. The test wasn’t shown in the
TestExplorer window. No bueno.
The problem here, quite obviously, is that the
async test function is returning
void. The test runner expects something back on which it can await, but I am giving it nothing. This causes the test runner to exit. I wish it were more obvious, but there is no success, error, or inconclusive result – just a Test Explorer window without my test function.
After correcting the test by simply changing the return type to
Task, life is good again. The Test Explorer shows my test and I can set breakpoints which actually pause execution of the test:
Again, when writing any function that uses
async in C#, you must NEVER return
async keyword means that you intend to return something upon which the caller will await. It’s just that easy.
If you are interested in a deep dive on this topic, I would recommend that you check out this article by Stephen Cleary: http://msdn.microsoft.com/en-us/magazine/dn818493.aspx. He has published books, articles, and blog posts surrounding all things C# asynchronous programming.
I'm a learner/coder/leader who is curious about how technologies and people work together to solve interesting problems. I have a passion for software and doing what I can to improve the lives of the people who create and use it.