How to get full coverage of C # async / await branches using nunit and opencover

In C #, async and wait becomes a state machine at compile time. My problem concerns every part of the state machine. I decompiled the code and ran the same unit test to see which branch I was missing.

    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            }

      

Above, you can see that line 59 hits 0 times in terms of coverage. According to this article http://www.codeproject.com/Articles/535635/Async-Await-and-the-Generated-StateMachine it gets hit when the machine is requested to stop. I have not been able to cancel the asynchronous call in a way that makes this happen.

This is a test that I thought would hit him, but it doesn't.

    [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);
    }

      

I have uploaded the sample to github

Using Asp.Net 4.5, Nunit 2.6.4, OpenCover 4.5.3522 and ReportGenerator 2.1.4.0

How do I get this string?

+3


source to share





All Articles