3

在继续进行其余的单元测试之前,我需要确保完成一项任务。

但这是在另一个方法中等待的任务(我正在对该方法进行单元测试。)

我试过等待任务或调用 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();
}

它失败的方式非常无益。它会导致另一个测试失败,并显示“测试运行时代理进程已停止”。(据我所知,这意味着后台线程在测试运行时抛出了异常。)

所以我想知道如何让我的代码等待单元测试完成。

我看到这个答案似乎相当不错。但它更适合于方法的调用。我不叫它,我只有任务。

注意:我的目标是使用 ansyc 包的 .NET 4.0。

4

2 回答 2

6

你不应该有一个void返回async方法,除非它是一个事件处理程序(在这种情况下你别无选择)。当一个async方法是void你无法知道它什么时候结束。

该方法应该返回 a TaskTask<T>如果它没有有意义的结果,则不是 a,只是表明它完成了)。

一旦它返回 aTask你就可以await在测试它时使用它,或者使用Wait,如果合适的话。

您正在等待该方法所依赖的任务之一,但这并不意味着它已经完成了它自己的代码。这意味着您的测试引入了竞争条件。

于 2013-01-10T22:03:10.120 回答
0

await myViewModel.DoStuff();只要点击 await 关键字,这个调用 就会返回(除非它很快完成)。另外,正如 Slaks 提到的,您不能等待 void 返回方法。

然后你 Wait onvar 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);
于 2013-01-10T22:01:19.413 回答