In a C# testing project, I have this test:
[TestMethod]
public void TestIfListFilled()
{
// arrange
byte stuffTypeID = 0;
List<Stuff> locationList = null;
// act
locationList = GetStuffListAsync(stuffTypeID);
// assert
Assert.IsTrue(locationList.Count > 0);
}
And the GetStuffListAsync
method has this signature:
Task<List<Stuff>> GetStuffListAsync(Byte stuffTypeID)
Now, my first guess was to add an await
before the method call in my test method. However, I can't add async
to my testmethod's signature, or Visual Studio will start complaining. What can I do to get my list filled before the assertion is performed?
You can make your unit test async
as well:
[TestMethod]
public async Task TestIfListFilled()
{
// arrange
byte stuffTypeID = 0;
// act
List<Stuff> locationList = await GetStuffListAsync(stuffTypeID );
// assert
Assert.IsTrue(locationList.Count > 0);
}
Note that using Result
instead could easily cause a deadlock, depending on the synchronization context your test runner has set up; you could end up with the async method's continuation waiting to get back onto a thread which is waiting for the async method to complete.
Note the change of the return type to Task
- this may be used by the unit test runner to detect completion in a cleaner way than the alternatives, and it's also useful to make sure that the test will break if you try to run it in a test runner which doesn't support async
tests.
If you want more control over how your underlying async operations work, it's possible to install your own synchronization context and creating tasks (to be returned by dependency fakes) which will only complete after you've stepped appropriately. It gets very complicated, but it's feasible - I have some sample code somewhere, but not handy...
See more on this question at Stackoverflow