单元测试异步操作
我想单元测试一下我执行和异步操作的方法:
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