使用代码生成来生成测试数据

Using code generation in order to generate test data

我经常遇到这样的情况,我想将一个大对象图的内容(运行-time 或在调试期间)保存到一组重新创建该对象图的语句中。然后可以将其用作单元测试用例中的测试数据。

认为对象图的叶子是标准类型(StringBigDecimalDate 等)并且分支遵循 bean 约定(getter、setter、空构造函数), 应该可以生成这种文件(例如TestData.java):

   public static Car createCar() {

    Wheel wheel1 = new Wheel();
    wheel1.setTypePressure( 2.1f );
    Wheel wheel2 = new Wheel();
    wheel2.setTypePressure( 2.3f );
    Wheel wheel3 = new Wheel();
    wheel3.setTypePressure( 2.0f );
    Wheel wheel4 = new Wheel();
    wheel4.setTypePressure( 2.8f );
    List<Wheel> wheels = new ArrayList<>( Arrays.asList( wheel1, wheel2, wheel3, wheel4 ) );

    Brake brake = new Brake();
    brake.setBrakeType( BrakeType.PLAIN );

    Car car = new Car();
    car.setBrake( brake );
    car.setWheels( wheels );
    car.setColor( "blue" );

    return car;
}

以某种方式将其直接插入调试会话真的很棒,但是将 "java object graph creation code with content" 输出结果写入 System.out 的一些插入语句也可以工作。

那么,我怎样才能以最有效的方式实现这一点呢?

好主意,但(可能是自以为是)不是最佳解决方案。

是的,数据 可以 转换为 Java 程序;然后需要保存,编译,...

然后就会出现这样的问题:你是想保留源代码,还是编译后的代码?版本控制(数据或底层 JRE)如何?

长话短说:Java 代码不是表示 数据 的一种非常方便的格式。因此:与其将数据转换为 Java 代码,不如将其转换为某种 JSON 表示形式。

重点是:当你的类真正关注"bean style"时;并且他们已经有了 getters/setters/default 构造函数 - 然后 any 体面的 JSON 解析器库应该工作 "out of the box"。您将 Car 对象扔向它;结果很好,标准 JSON。然后编写一个小帮助工具来读取此类文件并将它们转换回 Car 对象。完成。

这就是要走的路(这个建议来自于一个系统的工作人员,在这个系统上,架构师想要的正是您所要求的;我们花了很多时间和痛苦才到达那里......但那是 10 多年前的事了;而在 2017 年,你再也不会这样做了。

鉴于您的最新评论(因为您主要对单元测试代码感兴趣);我建议在此处研究使用 builder 模式。

这样你的代码就可以归结为

new CarBuilder().wheel(new WheelBuilder(). ...

好处是:有多种方法可以为您生成这样的构建器;例如项目 Lombok 有一个 @Builder 注释!

无论如何,自动生成构建器的市场还是很不错的

我不知道有任何 IDE 插件可以做到这一点,而且我无法通过谷歌搜索找到一个。在没有其他人编写的现有插件(为您的IDE)的情况下,您问题的答案:

How can I realize this in the most efficient way?

取决于 开发 插件(你自己!)或继续手动编写测试用例是否更有效。

我的猜测是后者会更有效率。


我也同意@GhostCat 的观点。如果您的测试用例是 "data intensive",最好为测试数据选择/实现一种 text-based 串行格式,并以这种方式表达测试数据。根据我的经验,以这种方式表示的测试数据比被编码为一堆 Java 调用以构建对象图的测试数据更容易读取/修改。重要的是你的测试用例不是 "write only".

我会考虑将您的图形持久化为某种 human-readable 但可解析的形式。 XML 可能是您的最佳选择,因为语法允许 cross-document 引用,但任何格式都可以使用 - 即使是自定义语法。这将使您能够在运行时保留和传输图形,同时支持 easy-to-modify 和 -replicate 单元测试的测试图。