如何在JUnit测试中随机生成存根类验证对象NonNull属性?
JUnit测试验证NonNull属性 + 高效生成一次性存根的解决方案
嘿,我来给你几个实用的方案解决这个问题——既要生成一次性的测试存根,又要验证对象的非空属性,刚好匹配你的需求:
方案1:用Mockito快速生成存根(简单场景首选)
Mockito可以帮你一键创建Data的存根实例,不用手动new再逐个调用set方法,而且JUnit的生命周期会自动处理这些存根的销毁,完全符合"用后即毁"的要求。
首先确保你的测试依赖里包含Mockito(Maven的话直接在pom.xml加依赖就行),然后修改测试代码:
import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; import static org.junit.Assert.assertNotNull; public class CopyTest { private Copy fixture; private Data testData; @Before public void setUp() throws Exception { fixture = new Copy(); // 生成Data的存根实例 testData = Mockito.mock(Data.class); // 给存根的get方法设置返回值 Mockito.when(testData.getAction()).thenReturn("Action"); Mockito.when(testData.getTags()).thenReturn("Tags"); // 如果你的Data是普通POJO,想真实调用set方法的话,用spy代替mock: // testData = Mockito.spy(new Data()); // testData.setAction("Action"); // testData.setTags("Tags"); } @Test public void testNonNullProperties() { // 验证属性非空 assertNotNull("Action属性不能为null", testData.getAction()); assertNotNull("Tags属性不能为null", testData.getTags()); // 这里可以继续写Copy类的业务逻辑测试,比如把testData传给fixture做处理 } }
方案2:给Data加Builder模式(复杂POJO更简洁)
如果Data是你自己维护的POJO,给它加个Builder类是个长期受益的做法——创建对象时代码更简洁,还能在Builder里提前做非空校验,从根源保证生成的实例属性都非空。
先给Data类添加Builder:
public class Data { private String action; private String tags; // 私有构造,只能通过Builder创建 private Data(Builder builder) { this.action = builder.action; this.tags = builder.tags; } // 省略getter方法... public static class Builder { private String action; private String tags; public Builder action(String action) { this.action = action; return this; } public Builder tags(String tags) { this.tags = tags; return this; } public Data build() { // 提前校验属性非空,避免创建无效实例 if (action == null || tags == null) { throw new IllegalArgumentException("Action和Tags不能为null"); } return new Data(this); } } }
然后在测试里用Builder快速创建,还能结合UUID生成随机的属性值:
import org.junit.Before; import org.junit.Test; import static org.junit.Assert.assertNotNull; import java.util.UUID; public class CopyTest { private Copy fixture; private Data testData; @Before public void setUp() throws Exception { fixture = new Copy(); // 用Builder创建,同时生成随机唯一的属性值 testData = new Data.Builder() .action(UUID.randomUUID().toString()) .tags(UUID.randomUUID().toString()) .build(); } @Test public void testNonNullProperties() { assertNotNull(testData.getAction()); assertNotNull(testData.getTags()); } }
方案3:用Faker生成真实随机测试数据(大量测试场景)
如果需要生成大量不同的随机测试数据(比如参数化测试),用Faker库就很方便——它能生成看起来真实的随机字符串、日期、姓名等,让测试覆盖更多场景。
先添加Faker的Maven依赖,然后测试代码:
import org.junit.Before; import org.junit.Test; import com.github.javafaker.Faker; import static org.junit.Assert.assertNotNull; public class CopyTest { private Copy fixture; private Data testData; private Faker faker; @Before public void setUp() throws Exception { fixture = new Copy(); faker = new Faker(); // 生成随机属性值 testData = new Data(); testData.setAction(faker.lorem().sentence()); testData.setTags(faker.lorem().word()); } @Test public void testNonNullProperties() { assertNotNull(testData.getAction()); assertNotNull(testData.getTags()); } }
小技巧:用AssertJ让断言更优雅
如果你想让断言代码更易读、更灵活,可以用AssertJ库,它的API更流畅:
import static org.assertj.core.api.Assertions.assertThat; @Test public void testNonNullProperties() { assertThat(testData.getAction()).isNotNull().isNotBlank(); assertThat(testData.getTags()).isNotNull().isNotBlank(); }
最后补充一句:JUnit的@Before方法会在每个测试方法执行前重新初始化对象,测试结束后这些对象会被垃圾回收,完全满足你"使用后即销毁"的需求哦。
内容的提问来源于stack exchange,提问作者iftekhar iftekhar
相关产品推荐
相关产品推荐

