带有@Builder 的 Lombok @NonNull 注释未反映在测试覆盖率中

Lombok @NonNull annotation with @Builder not reflecting in test coverage

我在测试 lombok 注释 class 时遇到了一个问题。 说明:-

当我们用@Builder注解一个javaclass(POJO),并且有某个实例变量带有@NonNull约束,同时编写测试用例来检查NullPointerException,我们不能用构建器实例化 POJO 并期望它将针对空值 check.I 进行评估 class 并看到非空约束在生成的构建器 class 本身内部流动,这意味着甚至在我们构建 object.This 之前抛出空指针异常在某种意义上是正确的行为,但我需要知道我是否可以测试这种情况。

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

现在我需要测试在 'a' 为 Null 时抛出 NullPointerException 的情况。 对于这种情况,我有 2 个选择:

我的问题是关于第二部分的,因为第一部分可以正常工作。 当我删除这个时,我会得到类似的东西:-

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 个参数,并且构造函数将永远不会执行检查非 null 属性的条件,因为测试覆盖率将 fall.If 我们使用 @SuperBuilder ,这不会发生,因为它不会在构建器参数中使用 @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。 如果我以下列方式构建 Sample 对象,它应该足以满足我的情况:-

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

如果我想在构造函数级别测试 'a' 的 NPE,这里我没有明确地将参数 'a' 设置为 NULL。