如何使用nunit和opencover获得C#的async / await的完整分支覆盖

时间:2015-04-16 18:57:06

标签: c# nunit async-await code-coverage opencover

在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

如何涵盖该行?

0 个答案:

没有答案