我有一个方法,看起来像这样:
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);
}
我试着像这样进行单元测试:
[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();
}
我的Assert在我完成模拟的LookUpIdAsync之前被调用。在我的正常代码中,这正是我想要的。但是对于我的单元测试,我不希望这样。
我正在从使用BackgroundWorker转换为Async/Await。对于后台工作程序,这是正确的,因为我可以等待BackgroundWorker完成。
但是似乎没有办法等待一个空的方法.
如何对该方法进行单元测试?
9条答案
按热度按时间kfgdxczn1#
你应该避免
async void
。仅将async void
用于事件处理程序。DelegateCommand
(逻辑上)是一个事件处理程序,所以你可以这样做:并对它进行单元测试:
我推荐的答案在上面。但是如果你真的想测试一个
async void
方法,你可以用我的AsyncEx library来做:但是这个解决方案在视图模型的生命周期中改变了
SynchronizationContext
。erhoui1w2#
async void
方法本质上是一个“fire and forget”方法。没有办法获取完成事件(没有外部事件等)。如果你需要对它进行单元测试,我建议将它改为
async Task
方法。然后,您可以对结果调用Wait()
,它将在方法完成时通知您。然而,这种测试方法仍然不能工作,因为您实际上并不是直接测试
DoStuff
,而是测试 Package 它的DelegateCommand
。您需要直接测试此方法。qnakjoqk3#
我想出了一个单元测试的方法:
这里的关键是,因为我是在进行单元测试,所以我可以在任务中替换我想要返回的BRAC调用(在BRAC void中)。然后,我只是确保任务已经完成,然后我继续前进。
0mkxixxg4#
我知道的唯一方法是将
async void
方法转换为async Task
方法m528fe3b5#
所提供的答案测试命令而不是CNOrc方法。正如上面提到的,你还需要另一个测试来测试这个方法。
在花了一些时间处理类似的问题后,我发现在单元测试中测试一个J2EE方法很容易,只需同步调用:
其使用方法:
测试在这一行等待,并在结果准备好后继续,因此我们可以在之后立即Assert。
57hvy0tb6#
您可以使用AutoResetEvent来暂停测试方法,直到AutoResetc调用完成:
omqzjyyz7#
更改方法以返回Task,然后可以使用Task.Result
js81xvg68#
我最终采用了一种不同的方法,这是在https://learn.microsoft.com/en-us/archive/msdn-magazine/2013/march/async-await-best-practices-in-asynchronous-programming#avoid-async-void上提出的
您的
async void
方法所做的就是在内部调用此async Task
方法。然后,在我的测试中,我没有调用
async void
方法,而是调用了async Task
方法。3gtaxfhh9#
我也有类似的问题。在我的例子中,解决方案是在
.Returns(...)
的moq设置中使用Task.FromResult
,如下所示:另外,Moq也有一个
ReturnsAysnc(...)
方法。