我正在为我的应用程序的"粘合"层编写单元测试,并且很难为异步方法创建确定性测试,允许用户过早地取消操作.
具体来说,在一些异步方法中,我们有代码响应取消调用并确保对象在完成之前处于正确状态.我想确保测试涵盖这些代码路径.
在此场景中举例说明典型异步方法的一些C#伪代码如下:
public void FooAsync(CancellationToken token, Action<FooCompletedEventArgs> callback)
{
if (token.IsCancellationRequested) DoSomeCleanup0();
// Call the four helper methods, checking for cancellations in between each
Exception encounteredException;
try
{
MyDependency.DoExpensiveStuff1();
if (token.IsCancellationRequested) DoSomeCleanup1();
MyDependency.DoExpensiveStuff2();
if (token.IsCancellationRequested) DoSomeCleanup2();
MyDependency.DoExpensiveStuff3();
if (token.IsCancellationRequested) DoSomeCleanup3();
MyDependency.DoExpensiveStuff4();
if (token.IsCancellationRequested) DoSomeCleanup4();
}
catch (Exception e)
{
encounteredException = e;
}
if (!token.IsCancellationRequested)
{
var args = new FooCompletedEventArgs(a bunch of params);
callback(args);
}
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,我提出的解决方案涉及模拟MyDependency由胶层包裹的基础操作,并强制每个人在任意时间段内休眠.然后我调用异步方法,并告诉我的单元测试在取消异步请求之前休眠几毫秒.
像这样的东西(以Rhino Mocks为例):
[TestMethod]
public void FooAsyncTest_CancelAfter2()
{
// arrange …Run Code Online (Sandbox Code Playgroud)