2012-04-26 115 views
2

我正在使用Visual Studio 2010 Ultimate SP1。我在我的项目中进行了大约225次单元测试,并且全部都通过了。然而,其中一项测试报告其击中方法的代码覆盖率为0%。在调试时,我可以一步一步看到它碰到了方法的每一行。然而在代码覆盖率报告中,它表明该方法根本没有被覆盖。所有其他测试和方法在代码覆盖方面工作得很好。VS2010代码覆盖率不准确

我尝试没有成功如下:

  • 感动被测试到另一个类的方法。
  • 使方法
  • 静态与非静态。
  • 将测试移至另一个班级。
  • 删除了所有的我的.testsetting文件,并从头开始重建他们
  • 写了不同的测试行使同样的方法,用相同的结果
  • 重启VS
  • 重启

如果它很重要,该方法在Global.asax文件中。但是,我把它移到另一个班上,没有什么区别。

任何想法?

以下是正在测试的方法。

public void LogError(ILoggingService loggingService, IController controller) 
    { 
     if (loggingService == null) 
      throw new ArgumentNullException("loggingService"); 

     if (controller == null) 
      throw new ArgumentNullException("controller"); 

     Exception ex = Server.GetLastError(); 

     loggingService.LogException(ex.Message, ex.StackTrace, ApplicationName.VoucherLog, UserInfo.UserName); 


     HttpException httpException = ex as HttpException; 

     if (httpException == null) 
     { 
      var routeData = new RouteData(); 
      routeData.Values["controller"] = "Error"; 
      routeData.Values["action"] = "HttpError"; 

      Server.ClearError(); 

      var rc = new RequestContext(new HttpContextWrapper(Context), routeData); 
      controller.Execute(rc); 
     } 
    } 

其中引发异常的前4行被其他测试命中,并显示在代码覆盖率统计中。该方法的其余部分由以下测试命中(通过调试来验证,并且看到实际上每行都被执行),但不会显示在代码覆盖率统计信息中。下面是测试:

[TestMethod] 
    [HostType("Moles")] 
    public void LogError() 
    { 
     DMVCommon.ApplicationName expectedApplication = DMVCommon.ApplicationName.VoucherLog; 
     string expectedUser = System.Security.Principal.WindowsIdentity.GetCurrent().Name; 
     NotImplementedException expectedException = null; 

     System.Web.Moles.MHttpServerUtility.AllInstances.GetLastError = (System.Web.HttpServerUtility server) => 
     { 
      return expectedException; 
     }; 

     System.Web.Moles.MHttpApplication.AllInstances.ContextGet = (System.Web.HttpApplication application) => 
     { 
      return MvcMockHelpers.FakeHttpCurrentContext(); 
     }; 


     try 
     { 
      throw new NotImplementedException(); 
     } 
     catch (NotImplementedException exc) 
     { 
      expectedException = exc; 
      using (MvcApplication app = new MvcApplication()) 
      { 
       bool called = false; 

       Mock<ILoggingService> mockLoggingService = new Mock<ILoggingService>(); 
       mockLoggingService.Setup(a => a.LogException(expectedException.Message, expectedException.StackTrace, expectedApplication, expectedUser)).Callback(() => called = true); 

       Mock<IController> mockController = new Mock<IController>(); 

       app.LogError(mockLoggingService.Object, mockController.Object); 

       mockController.Verify(a => a.Execute(It.IsAny<System.Web.Routing.RequestContext>()), Times.Exactly(1)); 
       Assert.IsTrue(called); 
      } 
     } 
    } 
+0

您是否正在RELEASE中运行coverage?你能告诉我们这个方法吗? – seldary 2012-04-30 05:30:23

+0

我在DEBUG中运行。但是,在你问我在RELEASE中再次尝试后,结果没有什么不同。我使用代码更新了问题,包括测试和正在测试的方法。顺便说一句,我们使用Moq和Moles。 – jvaran 2012-04-30 14:10:46

回答

0

这可能是因为您的Moles使用的 - 由于亚军加载程序集,痣接管及型材组装,而不是覆盖分析器。

已经有known integration issues与覆盖工具和莫莱斯 - 为了两个净分析器(摩尔&覆盖)一起工作,他们必须实现对彼此的具体支持。

尝试用痣运行,看看会发生什么......

也看到this作为一个类似的例子。

+0

是的,就是这样!当我评论出正在被移动的线条和测试中的痣时,它们都按预期工作。所以我想现在我最好的行动方式就是将[ExcludeFromCodeCoverage]属性添加到方法中,并附带一条评论,解释它实际上被覆盖,为什么?我唯一担心的是未来可能会改变覆盖范围的代码更改不一定会被注意到。 – jvaran 2012-05-01 12:47:07