2016-02-03 23 views
0

我正在運行PowerMock 1.6.4和所有最新的(JUnit 4.11雖然)。離線Jacoco使用MockStatic導致重新檢測異常

  • 我使用Jacoco Ant任務來檢測類而不是測試類。我還使用Jacoco ant任務來運行Junit測試,然後生成報告。

現在我打,我想不通一個問題...

  • 我有一個測試類,測試類Foo的一個成員函數。
  • Foo的一個成員是靜態的,所以我把它包裝在一個靜態函數中,所以我可以通過模擬來控制執行,但副作用是我現在需要mockStatic。

我已經注意到的是,PowerMockito.mockStatic(讓Foo.class) ...所有的測試失敗,儀器儀表的問題。

我有另一個測試類,測試Foo的另一個成員函數。這個測試類可以正常工作,但只要我引入了一個mockStatic,測試類就會失敗,儀器失敗。

有沒有人看到這個失敗,並知道任何解決方法?我無法更改靜態成員變量。

+0

我相信儀器需要在測試上完成,而不是在類上完成。至少在我的項目中,唯一需要測試的是我的測試類,而我的其他類不包括在內。試試這個,如果它不起作用,發佈你的pom/ant文件,這樣我可以再看一下它。 – Lencalot

回答

0

我終於弄清楚了我認爲的問題。 Jacoco儀器將數據注入字節碼,PowerMock在嘗試模擬靜態時也如此。這是因爲他們正在彼此踩踏而造成的破壞,由於他們彼此混淆,你會得到非常奇怪的行爲。我在代碼中得到了一堆不應該拋出NPE的NPE。

簡單的解決方案是重構出不必要的靜態信息,並知道如果您計劃使用靜態來控制數據流,那麼可能應該重新考慮用於測試的體系結構,如果您計劃使用Jacoco進行覆蓋。

您仍然可以在靜力學上運行Jacoco儀器,但不能同時模擬靜態;至少不會像PowerMock和Mockito一樣。我不確定EasyMock是否會導致不同的行爲,所以ymmv。

0

我有類似的問題,但沒有必要重構靜態,我相信有另一種解決方案。我在maven pom文件中這樣做了,但我會解釋發生了什麼。 Jacoco確實將數據注入到字節碼中。是的Powermock使用一個自定義的字節加載器和雅科克討厭。所以繼承人解決方案來解決它。

在您的Jacoco執行中,您需要Jacoco來爲您的測試使用默認檢測。 (你可以指定powermock測試或者只是包括所有測試它可以工作)。下面解釋什麼是默認的 - 儀表:Offline-instrumentation with Jacoco

然後您必須具有測試的恢復步驟。現在繼承了有趣的部分,您必須運行正常的Jacoco Prepare Agent步驟,同時排除所有在默認儀器中運行的測試。 (如果你沒有,你會得到一堆的警告類似JaCoCo exceution數據已經存在XTEST)

這將解決你的問題,你並不需要重構你的靜態方法。雖然如果他們是不必要的,你應該仍然可以把它們取出;)

<plugin> 
       <groupId>org.jacoco</groupId> 
       <artifactId>jacoco-maven-plugin</artifactId> 
       <version>${jacoco.version}</version> 
       <configuration> 
        <append>true</append> 
       </configuration> 
       <executions> 
        <execution> 
         <id>default-instrument</id> 
         <goals> 
          <goal>instrument</goal> 
         </goals> 
         <configuration> 
          <includes> 
           <include>**/*test*</include> 
          </includes> 
         </configuration> 
        </execution> 
        <execution> 
         <id>default-restore-instrumented-classes</id> 
         <goals> 
          <goal>restore-instrumented-classes</goal> 
         </goals> 
         <configuration> 
          <includes> 
           <include>**/*test*</include> 
          </includes> 
         </configuration> 
        </execution> 
        <execution> 
         <id>Prepare-Jacoco</id> 
         <goals> 
          <goal>prepare-agent</goal> 
         </goals> 
         <configuration> 
          <excludes> 
           <exclude>**/*test*</exclude> 
          </excludes> 
         </configuration> 
        </execution> 
       </executions> 
      </plugin>