如何编写单元测试来检查复制构造函数是否与类属性同步?

How to write a unit test to check copy constructor is in sync with class properties?

提问人:nilgun 提问时间:12/20/2018 最后编辑:Mark Rotteveelnilgun 更新时间:12/20/2018 访问量:1673

问:

最近,我们的系统中出现了一个错误,这是由于忘记在复制构造函数中分配新添加的类属性引起的。

例如:

public class MyClass {

    private Long companyId;
    private Long classId;
    private Double value;   <=  newly added

    public MyClass(MyClass myClass) {
        this.setCompanyId(myClass.getCompanyId());
        this.setClassId(myClass.getClassId());
        this.setValue(myClass.getValue());   <= we forget this line
    }

我想编写一个单元测试,以保证在添加新属性时捕获缺少的副本分配。我应该如何进行?

Java 单元测试 junit copy-constructor

评论

3赞 Roy Shahaf 12/20/2018
通过使字段成为最终字段,可以强制构造函数设置所有字段
0赞 Makoto 12/20/2018
@RoyShahaf:如果这是站不住脚的,那怎么办?不能保证这是使用可以处理该字段的构建器构建的,否则可能无法设置某些字段。这并不是要保证存在一个值,而是要保证这些值在实例之间是相同的。 在这种情况下,是一个完全可以接受的值。null
0赞 nilgun 12/20/2018
@RoyShahaf:我不想强制执行final,只是为了复制构造函数。我们很容易忘记进入决赛,给我们留下同样的问题。
0赞 Roy Shahaf 12/20/2018
@Makoto在某些情况下,确实是一个完全可以接受的值。自从使用 null 被认为是好的做法以来已经有一段时间了,如果你能够避免这样做(如果这样的时间曾经存在的话)。
1赞 Mark Rotteveel 12/20/2018
@RoyShahaf 如果所有字段都是最终字段,则可能不需要复制构造函数(除非它对其他可变对象进行深度复制)。

答:

0赞 Makoto 12/20/2018 #1

我会通过反思来做到这一点。

  • 新建 的实例。(一)MyClass
  • 通过反射,为每个字段分配一个值。这可以通过 来完成。getClass().getDeclaredFields()
  • 新建一个 的空白实例。(二)MyClass
  • 在 A 上针对 B 运行复制构造函数。
  • 通过反射,确定 A 中的字段是否等于 B。

评论

0赞 nilgun 12/20/2018
在第 2 步中,为每个字段分配一个值可能有点棘手,因为在实际场景中,我们也有复杂的类作为类属性,您怎么看?
0赞 Makoto 12/20/2018
如果它们是复制构造函数的一部分,则别无选择。您必须保证每个字段都匹配,无论多么复杂。
0赞 nilgun 12/20/2018
你能提供一个复杂对象的示例代码吗,我不确定如何用反射来做到这一点
0赞 M. Prokhorov 12/20/2018
我希望复制构造函数不会克隆字段值,因此按标识进行比较应该可以正常工作。