簡體   English   中英

帶有@Builder 的Lombok @NonNull 注釋未反映在測試覆蓋率中

[英]Lombok @NonNull annotation with @Builder not reflecting in test coverage

我在測試帶注釋的class時遇到了一個問題。 描述:-

當我們使用 @Builder 注釋 java 類(POJO),並且具有帶有@Builder約束的某些實例變量@NonNull ,在編寫測試用例以檢查NullPointerException時,我們無法使用 builder 實例化POJO ,並期望它會根據 null 檢查進行評估。 I delomboked the class and saw that the non null constraint flows inside the generated builder class itself which means a null pointer exception is thrown even before we construct the object.This is a correct behavior in some sense but I needed to know if I can test這樣的場景。

@Builder
public class Sample {
    @NonNull
    private final String a;
    private final String b;
}

現在我需要測試在“a”是 Null 的情況下拋出 NullPointerException 的情況。 對於這種情況,我有 2 個選項:

  • 我可以使用構造函數創建示例 class - new Sample(null, null)
  • 或者我可以通過構建器創建 - Sample.builder.a(null).build();

我的問題在第二部分,因為第一個可以正常工作。 當我delombok時,我會得到類似的東西:-

public class Sample {
    @NonNull
    private final String a;
    private final String b;

    Sample(@NonNull String a, String b) {
        this.a = a;
        this.b = b;
    }

    public static SampleBuilder builder() {
        return new SampleBuilder();
    }

    public static class SampleBuilder {
        private @NonNull String a;
        private String b;

        SampleBuilder() {
        }

        public SampleBuilder a(@NonNull String a) {
            this.a = a;
            return this;
        }

        public SampleBuilder b(String b) {
            this.b = b;
            return this;
        }

        public Sample build() {
            return new Sample(a, b);
        }

        public String toString() {
            return "Sample.SampleBuilder(a=" + this.a + ", b=" + this.b + ")";
        }
    }
}

在這里,如果您看到 NullPointerException 將被拋出 SampleBuilder 本身,因為它需要@NonNull arguments 並且構造函數將永遠不會執行條件來檢查非 null 屬性,因為測試覆蓋率將會下降。如果我們使用@SuperBuilder ,這將不會發生在構建器 arguments 中不采用@NonNull

不太確定您在期待什么,但下面的源代碼可以正確測試示例 class 的構造函數和生成器的null檢查。

您可以看到它在https://repl.it/repls/CleverWiryTruespace運行。

import lombok.NonNull;
import lombok.Builder;
import org.junit.Rule;
import org.junit.Test;
import org.junit.Before;
import org.junit.rules.ExpectedException;
import org.junit.runner.JUnitCore;

class Main {
  @Builder
  public static class Sample {
      @NonNull
      private final String a;
      private final String b;
  }

  public static class TestSample {
    @Rule
    public ExpectedException thrown = ExpectedException.none();

    @Before
    public void setUp() {
      thrown.expect(NullPointerException.class);
      thrown.expectMessage("a is marked non-null but is null");
    }

    @Test
    public void test1() {
      Sample s = new Sample(null, "abc");
    }

    @Test
    public void test2() {
      Sample.builder().a(null).build();
    }
  }

  public static void main(String[] args) {
    new JUnitCore().main(TestSample.class.getName());
  }
}

從代碼中我們可以看到,如果我們想在構造函數級別觸發 NPE,我們需要將 @NonNull 參數保留為空,而不是將其設置為 null,這將觸發構建方法級別的 NPE。 如果我以下列方式構建樣本 object 就足夠了:-

Sample sample = Sample.builder.b("b").build();

如果我想在構造函數級別測試“a”的 NPE,這里我沒有將參數“a”顯式設置為 NULL。

暫無
暫無

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

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