You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java测试类中将对象属性插入List属性的实现是否存在隐患?

结论

你这段代码在当前单测试用例的场景下功能是正常的,但确实存在坏味道,且在特定写法下会触发隐蔽的BUG。


正常运行的逻辑前提

JUnit4的@Before注解方法会在每一个@Test方法执行前独立执行一次,也就是说每个测试用例拿到的object都是全新的实例,objects也是全新的空列表,你现在单独跑firstTest的逻辑是完全没问题的,断言也能正常通过。


存在的坏味道和潜在问题

  • 同一个对象多次加入列表会出现联动修改BUG
    Java集合的add方法存储的是对象引用,不是对象副本,如果你后续对同一个实例做属性修改,列表里所有指向该实例的引用对应的属性都会同步变更,比如下面的写法就会不符合预期:
@Test
public void wrongTest() {
    object.setProperty("n1");
    objects.add(object);
    object.setProperty("n2");
    objects.add(object);
    // 预期两个元素属性分别是n1、n2,实际两个元素的属性都是n2
}
  • 测试类全局变量的写法冗余且易出错
    把object和objects抽成类属性完全没有必要:

    1. 变量边界模糊,后续如果有人误删@Before里的初始化逻辑,或者把@Before改成全局只执行一次的@BeforeClass,所有测试都会直接报错
    2. 读者需要额外向上查找变量初始化逻辑,增加代码理解成本
  • 当前断言写法存在语法缺陷
    你写的assert(objects.get(0).getProperty().equals("n1");缺少右括号,而且裸用Java关键字assert的报错信息非常模糊,建议使用JUnit自带的断言方法比如assertEquals。


优化后的写法参考

public class TestingClass {

    @Test
    public void firstTest() {
        List<CustomObject> objects = new ArrayList<>();
        CustomObject object = new CustomObject();
        object.setProperty("n1");
        objects.add(object);
        assertEquals("n1", objects.get(0).getProperty());
    }

    // 多测试复用的初始化逻辑可以抽成私有工具方法
    private CustomObject buildCustomObject(String property) {
        CustomObject obj = new CustomObject();
        obj.setProperty(property);
        return obj;
    }

    @Test
    public void testAddMultipleObjects() {
        List<CustomObject> objects = new ArrayList<>();
        objects.add(buildCustomObject("n1"));
        objects.add(buildCustomObject("n2"));
        assertEquals("n1", objects.get(0).getProperty());
        assertEquals("n2", objects.get(1).getProperty());
    }
}

内容的提问来源于stack exchange,提问作者jpestana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 22:42:01