Search code examples
vb.netvisual-studio-2010code-coveragemstest

How do I get 100% code coverage for "catch with rethrow" block in VB.NET in Visual Studio 2010 Ultimate?


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)

Source in C#


Equivalent source in VB.NET: (yellow background indicates partial code coverage)

Source in VB.NET


MSTests for both C# and VB.NET source (intended to achieve 100% code coverage)

MSTests


Code Coverage Report

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

Solution

  • 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.