MattHoneycutt / SpecsFor

SpecsFor is a light-weight Behavior-Driven Development framework that focuses on ease of use for *developers* by minimizing testing friction.
http://specsfor.com
MIT License
197 stars 70 forks source link

What is the correct way to test async method? #97

Closed rosdi closed 8 years ago

rosdi commented 8 years ago

Hi Matt,

This isn't an issue... I just want to know the correct way to test async method. Currently I call .Result like so...

protected override void When()
 {               
    result = SUT.MyAwesomeMethodAsync(param).Result;
 }

Is this the correct way?

ChuckBryan commented 8 years ago

Hi rosdi -

All I ever do is put the async keyword in the method signature and an await before the SUT Method (assuming that it is awaitable)

protected override **async** void When()
 {               
    result = **await**  SUT.MyAwesomeMethodAsync(param).Result;
 }
rosdi commented 8 years ago

Hi Chuck... but it is generally considered bad practice to return void on async method right? http://haacked.com/archive/2014/11/11/async-void-methods/

Maybe it is considered ok for SpecsFor scenario but I just want to make sure I am doing it the proper way here...

ChuckBryan commented 8 years ago

You know...I was just looking at that yesterday and did not apply that to my specs :)

I think that When would need to return a Task, right? I just noticed that many test runners will let you create a Test that Returns Task instead of void:

https://msdn.microsoft.com/en-us/magazine/dn818493.aspx

So, based on that article, I think you could do the following until there is a Task:

protected override void When()
{
    Task.Run(async () =>
    {
        result = await SUT.MyAwesomeMethodAsync(param).Result;
    }).GetAwaiter().GetResult();
}

It's a bit verbose.

MattHoneycutt commented 8 years ago

In 99% of cases, you should be fine with just calling .Result on your async method. I've done that on many a project without issue.

I might add support for async directly in the future, perhaps after I get things running on NUnit 3....