I am unable to achieve 100% code coverage for a "catch with rethrow" block in my VB.NET source code. My workplace IDE is Visual Studio 2010 Ultimate. Below example represents a simplified version of my actual problem.
Source in C#: (light-blue background indicates full code coverage)
Equivalent source in VB.NET: (yellow background indicates partial code coverage)
MSTests for both C# and VB.NET source (intended to achieve 100% code coverage)
Code Coverage Report
The code coverage report shows 100% for C#, but only 91.67% for VB.NET. It also shows 1 block of code with 0 lines being uncovered in VB.NET.
Is this an issue with the tool? Or am I missing something obvious?
EDIT #1: Sharing source code as requested by @Raptor
Source code in C#
public class CodeCoverage
{
public void DoWork(bool flag = false)
{
try
{
Thread.Sleep(1);
if (flag)
{
throw new Exception("test");
}
}
catch (Exception ex)
{
throw new Exception(string.Format("something happened: {0}", ex.Message));
}
}
}
Source code in VB.NET
Public Class CodeCoverage2
Public Sub DoWork(Optional ByVal flag As Boolean = False)
Try
Thread.Sleep(1)
If flag Then
Throw New Exception("test")
End If
Catch ex As Exception
Throw New Exception(String.Format("something happened: {0}", ex.Message))
End Try
End Sub
End Class
Source code for MSTests
[TestClass]
public class CodeCoverageTest
{
[TestMethod]
public void DoWorkTest()
{
var obj = new CodeCoverage();
obj.DoWork();
}
[TestMethod]
[ExpectedException(typeof(Exception))]
public void DoWorkTest2()
{
var obj = new CodeCoverage();
obj.DoWork(true);
}
[TestMethod]
public void DoWorkTest3()
{
var obj = new CodeCoverage2();
obj.DoWork();
}
[TestMethod]
[ExpectedException(typeof(Exception))]
public void DoWorkTest4()
{
var obj = new CodeCoverage2();
obj.DoWork(true);
}
}
If you look at the IL generated for the VB project in debug mode, you will see the following in the catch block:
IL_002f: call string [mscorlib]System.String::Format(string, object)
IL_0034: newobj instance void [mscorlib]System.Exception::.ctor(string)
IL_0039: throw
IL_003a: call void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::ClearProjectError()
IL_003f: leave.s IL_0041
Since IL_0039
throws, you would never hit IL_003a
, so you have code that never gets executed.
In release mode, the IL for ClearProjectError is not generated.