等到在单元测试中的所有任务完成 [英] Wait until all Task finish in unit test

查看:90
本文介绍了等到在单元测试中的所有任务完成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个类我想单元测试:

I have this class I want to unit test:

public class SomeClass
{
    public void Foo()
    {
        Bar();
    }

    private void Bar()
    {
        Task.Factory.StartNew(() =>
        {
            // Do something that takes some time (e.g. an HTTP request)
        });
    }
}

这是我的单元测试的样子:

And this is how my unit test looks like:

[TestMethod]
public void TestFoo()
{
    // Arrange
    var obj = new SomeClass();

    // Act
    obj.Foo();
    obj.Foo();
    obj.Foo();

    // Assert
    /* I need something to wait on all tasks to finish */
    Assert.IsTrue(...);
}

所以,我需要做单元测试的线程等待,直到所有任务在酒吧方法启动开始我断言之前已经完成了他们的工作。

So, I need to make the unit test thread wait until all tasks started in the Bar method have finished their job before starting my assertions.

重要提示:我不能改变 SomeClass的

我怎么能这样做?

推荐答案

要解决这个问题,就是以这样的方式,将让你保持你的嵌套任务的完成跟踪定义自己的任务调度的方法之一。例如,您可以定义同步执行任务的调度,如下:

One way to solve this problem is to define your own task scheduler in such a way that would allow you to keep track of the completion of your nested tasks. For example, you could define a scheduler that executes tasks synchronously, as below:

class SynchronousTaskScheduler : TaskScheduler
{
    protected override void QueueTask(Task task)
    {
        this.TryExecuteTask(task);
    }

    protected override bool TryExecuteTaskInline(Task task, bool wasPreviouslyQueued)
    {
        return this.TryExecuteTask(task);
    }

    protected override IEnumerable<Task> GetScheduledTasks()
    {
        yield break;
    }
}

随后,创建此同步任务调度的一个实例,并用它来执行任务的根,这反过来,产卵所有的隐藏的任务。由于嵌套任务继承父当前任务调度程序,您的所有内部的任务也将得到我们的同步调度运行,这意味着我们的最外层的 StartNew 调用将只返回当所有任务完整的。

Subsequently, create an instance of this synchronous task scheduler, and use it to execute a root task which, in turn, spawns all of your "hidden" tasks. Since nested tasks inherit the current task scheduler from their parent, all your inner tasks will also get run on our synchronous scheduler, implying that our outermost StartNew call will only return when all tasks complete.

TaskScheduler scheduler = new SynchronousTaskScheduler();

Task.Factory.StartNew(() =>
{
    // Arrange
    var obj = new SomeClass();

    // Act
    obj.Foo();
    obj.Foo();
    obj.Foo();
}, 
    CancellationToken.None,
    TaskCreationOptions.None,
    scheduler);

// Assert
/* I need something to wait on all tasks to finish */
Assert.IsTrue(...);

一个缺点这种方法,你将失去从你的任务的所有并发性;但是,您可以通过增强的定制调度其一是并发的解决这个问题,但仍允许你跟踪执行的任务。

A downside to this approach is that you will lose all concurrency from your tasks; however, you could fix this by enhancing the custom scheduler to one which is concurrent but still allows you to track executing tasks.

这篇关于等到在单元测试中的所有任务完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆