如何测试异步void方法
本文关键字:异步 void 方法 测试 何测试 | 更新日期: 2023-09-27 18:05:08
请考虑如下代码:通过调用GetBrands,属性Brands将被分配适当的数据。
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();
// ......
}
}
但是如果我按照如下所示进行测试,测试失败了。我如何等待方法GetBrands内部的异步调用?
[TestMethod]
public void AllBrandsTest()
{
BrandsViewModel viewModel = new BrandsViewModel();
viewModel.GetBrands();
Assert.IsTrue(viewModel.Brands.Any());
}
这里的简单答案是:不要让它成为async void
。事实上,永远不要使某些东西成为async void
,除非它绝对必须作为事件处理程序工作。async void
丢失的东西是,正是您想要在这里进行测试的东西(可能是您的实际代码)。
将其改为async Task
方法,现在您可以等待完成(超时)/添加延续,并检查它是成功退出还是异常退出。
这是一个单字更改,为:
public async Task GetBrands()
{
// ......
Brands = await _dataHelper.GetFavoriteBrands();
// ......
}
,然后在测试中:
[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");
}
您的模型(DTO)正在填充自己(数据访问)。这对一个班级来说太繁重了。通常当你问自己"我到底该如何测试这个"时,就该进行重构了。创建一个单独的数据访问类:
BrandsViewModel viewModel = new BrandsViewModel();
var brandAccess = new BrandsDataAccess();
viewModel.Brands = await brandAccess.GetAllBrands();
Assert.IsTrue(viewModel.Brands.Any());
现在可以测试BrandsDataAccess.GetAllBrands()
了