With .Net Core 3 we have a new IAsyncDisposable
interface that allows disposing objects asynchronously.
This may be used in two different ways:
await using var someVar = new SomeType();
or
var someVar = new SomeType();
await someVar.DisposeAsync();
It seems, SonarQube calculates conditions coverage incorrectly. Even if all lines are covered with tests, SonarQube marks the line with await using
as partially covered with tests (5 of 10 conditions covered) which is nonsense as there are no branches managed by a developer. With the second syntax, the line with DisposeAsync
is also marked as partially covered (1 of 2 conditions covered) - that’s better because does not affect overal metrics so badly but still may prevent us from passing quality gates.
The reproduction:
public class TestClass
{
public async Task Example1()
{
await using var trans = new MyTransaction();
}
public async Task Example2()
{
var trans = new MyTransaction();
await trans.DisposeAsync();
}
}
public class MyTransaction : IAsyncDisposable
{
public async ValueTask DisposeAsync()
{
}
}
public class UnitTest1
{
[Fact]
public async Task Test1()
{
var c = new TestClass();
await c.Example1().ConfigureAwait(false);
}
[Fact]
public async Task Test2()
{
var c = new TestClass();
await c.Example2().ConfigureAwait(false);
}
}
Expected behavior: treat TestClass as having 100% test coverage both by lines and by conditions.
SonarQube Data Center Edition Version 8.3.1 (build 34397)
Testing framework: XUnit 2.4.1
TargetFramework: netcoreapp3.0