在c#中,async和await在编译时被转换为状态机。我的问题是击中状态机的每一块。我已经反编译了代码并对它进行了完全相同的单元测试,以找出我缺少的分支。
49 void IAsyncStateMachine.MoveNext()
4 50 {
4 51 int result1 = 0;
52 try
4 53 {
4 54 bool flag = true;
55 TaskAwaiter<int> awaiter;
4 56 switch (this._state)
57 {
58 case -3:
0 59 goto label_6;
60 case 0:
1 61 awaiter = this._awaiter2;
1 62 this._awaiter2 = new TaskAwaiter<int>();
1 63 this._state = -1;
1 64 break;
65 default:
3 66 awaiter = this._this._additionAsync.Add(this.value1, this.value2).GetAwaiter();
2 67 if (!awaiter.IsCompleted)
1 68 {
1 69 this._state = 0;
1 70 this._awaiter2 = awaiter;
1 71 this._builder.AwaitUnsafeOnCompleted<TaskAwaiter<int>, CalculatorAsync.d__0>(ref awaiter, ref this);
1 72 flag = false;
1 73 return;
74 }
1 75 break;
76 }
2 77 int result2 = awaiter.GetResult();
2 78 awaiter = new TaskAwaiter<int>();
2 79 this._results1 = result2;
2 80 result1 = this._results1;
2 81 }
1 82 catch (Exception ex)
1 83 {
1 84 this._state = -2;
1 85 this._builder.SetException(ex);
1 86 return;
87 }
88 label_6:
2 89 this._state = -2;
2 90 this._builder.SetResult(result1);
4 91 }
上面你可以看到第59行在覆盖范围内命中了0次。 根据这篇文章http://www.codeproject.com/Articles/535635/Async-Await-and-the-Generated-StateMachine,当机器被要求停止时它会被击中。我无法以某种方式取消异步调用。
我认为这是一个测试,但不是。
[Test]
[ExpectedException("System.InvalidOperationException")]
public async void DecompiledCancellationTest()
{
var expectedResult = 4;
var tcs = new TaskCompletionSource<int>();
tcs.SetResult(4);
var additionHandler = new Mock<IAdditionHandler>();
additionHandler.Setup(x => x.Add(2, 2)).Returns(tcs.Task);
tcs.SetCanceled();
var calculator = new CalculatorAsync(additionHandler.Object);
var aTaskResponse = calculator.AddDecompiled(2, 2);
var aResponse = await aTaskResponse;
Assert.AreEqual(expectedResult, aResponse);
}
我已将示例上传到github
使用Asp.Net 4.5,Nunit 2.6.4,OpenCover 4.5.3522和ReportGenerator 2.1.4.0
如何涵盖该行?