我需要确保任务完成后再进行剩余的单元测试。
但是这是一个在另一个方法中等待的任务(我正在对该方法进行单元测试。)
我已经尝试等待任务或调用task.Wait()但每次测试都不起作用。
实际方法如下:
private async void DoStuff(long idToLookUp)
{
IOrder order = await orderService.LookUpIdAsync(idToLookUp);
OtherStuff = false;
}
我正试图对它进行单元测试:
[TestMethod]
public void TestDoStuff()
{
//+ Arrange
var lookupTask = Task<IOrderableTest>.Factory.StartNew(() => validOrder);
orderService.LookUpIdAsync(Arg.Any<long>()).Returns(lookupTask);
//+ Act
myViewModel.DoStuff();
await lookupTask;
//+ Assert
myViewModel.OtherStuff.Should().BeFalse();
}
失败的方式非常无益。 In It导致另一个测试失败,“测试运行时代理进程已停止”。 (据我所知,这意味着后台线程在测试运行时抛出异常。)
所以我想知道如何让我的代码等待单元测试完成。
我看到this答案似乎相当不错。但它更倾向于调用该方法。我不是在说它,我只是完成任务。
注意:我使用ansyc包定位.NET 4.0。
答案 0 :(得分:6)
你永远不应该有一个void
返回async
方法,除非它将成为一个事件处理程序(在这种情况下你别无选择)。当async
方法为void
时,您无法知道它何时结束。
该方法应该返回Task
(如果没有有意义的结果,则返回Task<T>
,只是表明它已完成)。
一旦它返回Task
,您可以在测试时await
,或者使用Wait
,如果这是合适的话。
您正在等待该方法所依赖的任务之一,但这并不意味着它已经完成了自己的代码。这意味着您的测试引入了竞争条件。
答案 1 :(得分:0)
一旦命中await关键字,该调用await myViewModel.DoStuff();
就会返回(除非它很快完成)。此外,正如Slaks所提到的,你无法等待一个无效的返回方法。
然后你等待var lookupTask = Task<IOrderableTest>.Factory.StartNew(() => validOrder);
除了返回IOrderableTest
之外,它似乎没什么用。
另外我不认为你应该做await lookupTask
,这将再次返回给调用者,在这种情况下,TestRunner不会/可能不会期望这个。
您应该使用lookupTask.Wait()
(这是阻止调用);并确保myViewModel.DoStuff();
也需要足够的时间来完成。
摘要:
private async Task DoStuff(long idToLookUp)
{
IOrder order = await orderService.LookUpIdAsync(idToLookUp);
OtherStuff = false;
return;
}
....
var task = myViewModel.DoStuff();
Task.WaitAll(task, lookupTask);