How to write unit tests with TPL and TaskScheduler

后端 未结 5 1586
离开以前
离开以前 2021-02-01 06:50

Imagine a function like this:

private static ConcurrentList list = new ConcurrentList();
public void Add(object x)
{
   Task.Factory.         


        
      
      
      
5条回答
  •  一个人的身影
    2021-02-01 07:31

    One way to do this is to make your type configurable such that it takes a TaskScheduler instance.

    public MyCollection(TaskScheduler scheduler) {
      this.taskFactory = new TaskFactory(scheduler);
    }
    
    public void Add(object x) {
      taskFactory.StartNew(() => {
        list.Add(x);
      });
    }
    

    Now in your unit tests what you can do is create a testable version of TaskScheduler. This is an abstract class which is designed to be configurable. Simple have the schedule function add the items into a queue and then add a function to manually do all of the queue items "now". Then your unit test can look like this

    var scheduler = new TestableScheduler();
    var collection = new MyCollection(scehduler);
    collection.Add(42);
    scheduler.RunAll();
    Assert.IsTrue(collection.Contains(42));
    

    Example implementation of TestableScehduler

    class TestableScheduler : TaskScheduler {
      private Queue m_taskQueue = new Queue();
    
      protected override IEnumerable GetScheduledTasks() {
        return m_taskQueue;
      }
    
      protected override void QueueTask(Task task) {
        m_taskQueue.Enqueue(task);
      }
    
      protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued) {
        task.RunSynchronously();
      }
    
      public void RunAll() {
        while (m_taskQueue.Count > 0) {
          m_taskQueue.Dequeue().RunSynchronously();
        }
      }
    }
    

提交回复
热议问题