How to test an async void method
async-await, c#, unit-testing
Solution
The simple answer here is: don't make it an `async void`. In fact, don't ever make something an `async void` unless it absolutely has to be to work as an event-handler. The things that `async void` loses are precisely the things that you want here for your test (and presumably for your real code).
Make it an `async Task` method instead, and you now have the ability to wait for completion (with timeout) / add a continuation, and to check whether it exited with success or an exception.
This is a single word change, to:
public async Task GetBrands()
{
// ......
Brands = await _dataHelper.GetFavoriteBrands();
// ......
}
and then in the test:
[TestMethod]
public async Task AllBrandsTest()
{
BrandsViewModel viewModel = new BrandsViewModel();
var task = viewModel.GetBrands();
Assert.IsTrue(task.Wait(YOUR_TIMEOUT), "failed to load in time");
Assert.IsTrue(viewModel.Brands.Any(), "no brands");
}
Problem
Please consider the code as shown below. By calling GetBrands, property Brands will be assigned with proper data. ``` public class BrandsViewModel : ViewModelBase { private IEnumerable<Brand> _brands; public IEnumerable<Brand> Brands { get { return _brands; } set { SetProperty(ref _brands, value); } } public async void GetBrands() { // ...... Brands = await _dataHelper.GetFavoriteBrands(); // ...... } } ``` But if I test it as shown below, the test failed. How do I wait for the async call inside method GetBrands? ``` [TestMethod] public void AllBrandsTest() { BrandsViewModel viewModel = new BrandsViewModel(); viewModel.GetBrands(); Assert.IsTrue(viewModel.Brands.Any()); } ```