[英]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 个选项:
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.