我有一个大类 Customer,我正在使用 groovy 的 @Builder 注释来生成构建器类。这工作正常,但是在编写单元测试时,我想要做的是使用所有默认值定义客户,然后从我的测试中我可以使用构建器类传递一些覆盖。我不想传递字段名称来覆盖字段,因为这很容易出错。
下面是我的建造者课程
@Builder(builderStrategy = ExternalStrategy, forClass = Customer.class, includeSuperProperties = true)
class CustomerBuilder {
}
这是我的测试构建器类,它接受类 CustomerBuilder 的参数并从单元测试调用方法,有什么方法可以合并这两个构建器以生成具有默认值和覆盖的客户对象
class TestDataBuilder {
public TestDataBuilder withDefaultCustomerOverrides(CustomerBuilder customerBuilder) {
CustomerBuilder customerBuilderDefault = new CustomerBuilder()
.modifiedDateTime(LocalDateTime.now())
.custName("Test Client")
//somehow merge the two builders
return customerBuilderDefault.build()
}
}
TestDataBuilder testDataBuilder = new TestDataBuilder()
testDataBuilder.withDefaultCustomerOverrides(new CustomerBuilder().custName("Custom Test Client"))
构建器只是即将用于创建的数据的容器 真实的物体。使用默认构建器时,不了解 构建器对象,无论是否设置了值(我确信,您可以创建 这是通过您必须首先创建的策略(最有可能是您自己)。
所以我们不能依赖构建器内部的数据来告诉我们,什么 值已设置:调用
id(null)
将 id
设置为 null
,
或者它是最初的默认值?那么如何合并这两个容器呢?
因此,不要传递构建器实例来与默认值合并 构建器实例,传入一个函数来转换构建器。这 您也可以保留常见的非默认设置的功能 然后组合/链接它们。
例如(见
XXX
评论)
import java.time.Instant
import groovy.transform.builder.*
import groovy.transform.ToString
import java.util.function.Function
@ToString
class Customer {
Long id
String name
String comment
Instant createdTS
Instant modifiedTS
}
@Builder(builderStrategy = ExternalStrategy, forClass = Customer.class, includeSuperProperties = true)
class CustomerBuilder {
}
// XXX: pass in a function for the transformation and apply it on the default builder
Customer withDefaults(Function<CustomerBuilder,CustomerBuilder> transformBuilder) {
transformBuilder.apply(
new CustomerBuilder()
.name("Default")
.createdTS(Instant.now())
).build()
}
println withDefaults {
it.id(42)
.modifiedTS(Instant.parse('2020-01-01T00:00:00.0Z'))
} // → Customer(42, Default, null, 2024-04-27T08:13:30.083152202Z, 2020-01-01T00:00:00Z)
// XXX: extract common configs, that are not default
Function withComment = {
it.comment("Comment")
}
println withDefaults(withComment) // → Customer(null, Default, Comment, 2024-04-27T08:13:30.056778031Z, null)
// XXX: combine common builders with other overrides
println withDefaults(withComment.andThen {
it.id(666)
}) // → Customer(666, Default, Comment, 2024-04-27T08:13:30.056778031Z, null)