在 Java 中,“不可变性(Immutability)”通常指对象创建后其状态不能被修改。测试不可变性,就是验证:无论怎么“操作”,原对象都不会发生变化。
下面从思路 → 常见测试方法 → 示例 → 工具系统说明。
一个类是不可变的,通常满足:
final 修饰(防止继承破坏)private finalList、Date):
核心原则:
修改“看起来能改的东西”,然后检查原对象是否变化
@Test
public void shouldNotHaveSetter() throws Exception {
Method[] methods = User.class.getDeclaredMethods();
for (Method m : methods) {
assertFalse(m.getName().startsWith("set"));
}
}
@Test
public void fieldShouldNotBeModified() throws Exception {
User user = new User("Tom");
Field field = User.class.getDeclaredField("name");
field.setAccessible(true);
field.set(user, "Jerry");
assertEquals("Tom", user.getName());
}
✅ 若抛异常或值不变 → 不可变
@Test
public void listShouldBeDefensiveCopy() {
List<String> tags = new ArrayList<>();
tags.add("a");
Config config = new Config(tags);
config.getTags().add("b");
assertEquals(1, config.getTags().size());
}
@Test
public void constructorDefensiveCopy() {
List<String> list = new ArrayList<>();
list.add("x");
Container c = new Container(list);
list.add("y");
assertEquals(1, c.getList().size());
}
@Test
public void withMethodReturnsNewInstance() {
Point p1 = new Point(1, 2);
Point p2 = p1.withX(10);
assertNotSame(p1, p2);
assertEquals(1, p1.getX());
}
<dependency>
<groupId>org.mutabilitydetector</groupId>
<artifactId>MutabilityDetector</artifactId>
<version>0.10.1</version>
</dependency>
@Test
public void shouldBeImmutable() {
assertImmutable(User.class);
}
classes().that().resideInAPackage("..domain..")
.should().beImmutable()
record User(String name) {}
✅ 编译器保证不可变
❌ 以下不是真正不可变:
public final class Bad {
private final List<String> list;
public List<String> getList() {
return list; // 暴露可变引用
}
}
测试不可变性 = 尝试破坏 + 验证不变
| 测试方向 | 是否必要 |
|---|---|
| 无 setter | ✅ |
| 反射改字段 | ✅ |
| 可变对象拷贝 | ✅ |
| 返回新对象 | ✅ |
| 工具检测 | ✅✅ |
如果你有具体类代码,我可以直接帮你写不可变性测试用例。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。