2012-04-26 116 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