Await an async void method call for unit testing
.net, async-await, c#, unit-testing, void
Solution
I figured out a way to do it for unit testing:
[TestMethod]
public void TestDoStuff()
{
//+ Arrange
myViewModel.IsSearchShowing = true;
// container is my Unity container and it setup in the init method.
container.Resolve<IOrderService>().Returns(orderService);
orderService = Substitute.For<IOrderService>();
var lookupTask = Task<IOrder>.Factory.StartNew(() =>
{
return new Order();
});
orderService.LookUpIdAsync(Arg.Any<long>()).Returns(lookupTask);
//+ Act
myViewModel.DoLookupCommand.Execute(0);
lookupTask.Wait();
//+ Assert
myViewModel.IsSearchShowing.Should().BeFalse();
}
The key here is that because I am unit testing I can substitute in the task I want to have my async call (inside my async void) to return. I then just make sure the task has completed before I move on.
Problem
I have a method that looks like this: ``` private async void DoStuff(long idToLookUp) { IOrder order = await orderService.LookUpIdAsync(idToLookUp); // Close the search IsSearchShowing = false; } //Other stuff in case you want to see it public DelegateCommand<long> DoLookupCommand{ get; set; } ViewModel() { DoLookupCommand= new DelegateCommand<long>(DoStuff); } ``` I am trying to unit test it like this: ``` [TestMethod] public void TestDoStuff() { //+ Arrange myViewModel.IsSearchShowing = true; // container is my Unity container and it setup in the init method. container.Resolve<IOrderService>().Returns(orderService); orderService = Substitute.For<IOrderService>(); orderService.LookUpIdAsync(Arg.Any<long>()) .Returns(new Task<IOrder>(() => null)); //+ Act myViewModel.DoLookupCommand.Execute(0); //+ Assert myViewModel.IsSearchShowing.Should().BeFalse(); } ``` My assert is called before I get done with the mocked up LookUpIdAsync. In my normal code, that is just what I want. But for my Unit test I don't want that. I am converting to Async/Await from using BackgroundWorker. With background worker this was functioning correctly because I could wait for the BackgroundWorker to finish. But there does not seem to be a way to wait for a async void method... How can I unit test this method?