单元测试异步操作

我想单元测试一下我执行和异步操作的方法:

 Task.Factory.StartNew(() =>
        {
            // method to test and return value
            var result = LongRunningOperation();
        });

我在我的单元测试(用C#编写)中存储必要的方法等,但问题是异步操作没有完成之前我断言测试。

我怎样才能解决这个问题? 我应该创建一个TaskFactory模拟或任何其他技巧来单元测试一个异步操作?


你必须有一些伪造任务创建的方法。

如果您将Task.Factory.StartNew调用移至某个依赖项( ILongRunningOperationStarter ),那么您可以创建一个替代实现,该实现使用TaskCompletionSource创建完成您想要的任务的任务。

它会变得有点毛,但它可以完成。 我前段时间在博客上写了这样的内容 - 单元测试接收任务的方法,这当然会让事情变得更容易。 它是在C#5中异步/等待的上下文中,但同样的原则适用。

如果你不想虚构出所有的任务创建,你可以更换任务工厂,并以这种方式控制时间 - 但我怀疑这会更加老练,说实话。


我会建议在你的方法中用一个特殊的实现来存储一个TaskScheduler用于单元测试。 您需要准备好代码以使用注入的TaskScheduler:

 private TaskScheduler taskScheduler;

 public void OperationAsync()
 {
     Task.Factory.StartNew(
         LongRunningOperation,
         new CancellationToken(),
         TaskCreationOptions.None, 
         taskScheduler);
 }

在您的单元测试中,您可以使用此博客文章中描述的DeterministicTaskScheduler在当前线程上运行新任务。 您的“异步”操作将在完成您的第一个断言陈述之前完成:

[Test]
public void ShouldExecuteLongRunningOperation()
{
    // Arrange: Inject task scheduler into class under test.
    DeterministicTaskScheduler taskScheduler = new DeterministicTaskScheduler();
    MyClass mc = new MyClass(taskScheduler);

    // Act: Let async operation create new task
    mc.OperationAsync();
    // Act:  Execute task on the current thread.
    taskScheduler.RunTasksUntilIdle();

    // Assert
    ...
}

尝试像这样...

object result = null;
Task t =  Task.Factory.StartNew(() => result = LongRunningThing()); 


Task.Factory.ContinueWhenAll(new Task[] { t }, () => 
{
   Debug.Assert(result != null);
});
链接地址: http://www.djcxy.com/p/50795.html

上一篇: unit testing asynchronous operation

下一篇: How to unit test asynchronous APIs?