簡體   English   中英

針對新代碼覆蓋范圍的SonarQube質量門因未發現依賴於Java烘焙的代碼而失敗

[英]SonarQube quality gate on new code coverage fails for uncovered code that relies on things baked into Java

我們團隊中的某人更改了此代碼:

public class Rectangle implements Cloneable, Serializable {

    @Override
    public Rectangle clone() {
        return new Rectangle(x, y, width, height);
    }

}

此代碼:

public class Rectangle implements Cloneable, Serializable {

    @Override
    public Rectangle clone() {
        try {
            // super.clone is safe to return since all of the Rectangle's fields are primitive.
            return (Rectangle) super.clone();
        } catch (CloneNotSupportedException e) {
            // should never happen since Cloneable is implemented
            return null;
        }
    }

}

他們編寫了一個覆蓋try代碼路徑的單元測試。

他們沒有編寫涵蓋catch代碼路徑的測試。 catch代碼路徑依賴於“烘焙”到Java中的內容,唯一的使崩潰的方法是通過刪除Cloneable標記接口來更改類的結構 但是,如果該類結構發生變化,則另一個單元測試將失敗。

由於單元測試未涵蓋catch代碼路徑,因此SonarQube質量門“新代碼的代碼覆蓋率”失敗,並且由於質量門失敗,構建該分支的Jenkins作業失敗,並且由於Jenkins作業失敗, Bitbucket不允許合並。

已經嘗試過:

  • 失敗:在SonarQube中標記為誤報:對於代碼覆蓋率質量門來說是不可能的,您只能對基於規則的問題執行此操作。
  • DIRTY HACK:運行作業之前關閉(或降低)SonarQube中的質量門,並在分支合並后重新打開:這是可行的,但是感覺很臟,我認為應該真的例外地發生。 我正在尋找不需要人工干預的更好解決方案。
  • 失敗: super.clone() Rectangle :將不起作用, super.clone() ,它位於Object.clone() ,后者是一種受保護的方法。
  • 失敗:通過添加其他類(例如, Rectangle > EvilRectangle > TestRectangle偽造它,其中EvilRectangle拋出CloneNotSupportedException ,然后TestRectangle是為該測試實例化的實際類。 無法使用,因為那樣會更改clone()方法的簽名,並且不會在Rectangle拋出CloneNotSupportedException

問題

  • Java人
  • 如何編寫catch代碼路徑的單元測試?
  • 如何在不更改公共API的情況下重寫代碼,使其成為可測試的?
  • SonarQube人
  • 如何使質量門“通過新代碼覆蓋代碼”通過?

編輯歷史

  • 添加了原始代碼

Apache Commons Lang提供了一個clone方法,該方法可以進行深層復制並且不會引發異常。 沒有例外意味着不需要try/catch ,因此要測試的代碼路徑更少。 我在討論Object.clone()替代方法的文章中發現了這一點: https : //dzone.com/articles/java-cloning-copy-constructor-vs-cloning

將此添加到pom.xml

<dependency>
  <groupId>commons-lang</groupId>
  <artifactId>commons-lang</artifactId>
  <version>2.6</version>
</dependency>

將此添加到您的類的import語句中:

import org.apache.commons.lang.SerializationUtils;

您的類必須具有implements Serializable 添加一個private static final long serialVersionUID ,這顯然是一種最佳實踐。

然后將super.clone()替換為SerializationUtils.clone(this)

最后,您可以刪除clone()語句周圍的try/catch ,或從方法中刪除trows

現在這是我的新代碼:

@Override
public Rectangle clone() {
    return (Rectangle) SerializationUtils.clone(this);
}

以前它已經被單元測試所覆蓋,並且該單元測試仍然通過。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM