为junit-quickcheck编写生成器时,可以轻松使用提供的Ctor
或Fields
反射方法。但直接在我的业务模型上应用反射可以防止我限制生成的数据(除非我将业务模型与快速检查注释交错)。
例如:
class Price {
public final BigDecimal price;
public final BigDecimal discountPercentage;
// With a constructor
}
price 字段可以是任何(合理的)BigDecimal(简称1000),但折扣必须介于0到100之间。
如何用惯用的方式编写生成器?
我目前的方法是创建一个指定要生成的模型的类:
class PriceFields {
public @InRange(max="1000") BigDecimal price;
public @InRange(max="100") BigDecimal discountPercentage;
public Price toPrice(){
return new Price(price, discountPercentage);
}
}
这样的发电机:
public class PriceGenerator extends Generator<Price> {
public PriceGenerator() {
super(Price.class);
}
@Override
public Price generate(SourceOfRandomness random, GenerationStatus status) {
return gen().fieldsOf(PriceFields.class)
.generate(random, status)
.toPrice();
}
}
但我希望能够写出这样的东西(没有PriceFields类):
public class PriceGenerator extends Generator<Price> {
public PriceGenerator() {
super(Price.class);
}
@Override
public Price generate(SourceOfRandomness random, GenerationStatus status) {
BigDecimal price = gen().???; // How to generate this constrained BigDecimal?
BigDecimal percentage = gen().???; // How to generate this constrained BigDecimal?
return new Price(price, percentage);
}
}
似乎Generators
API更适合内部使用,而不是自定义生成器,例如configure方法需要注释类型@InRange
,这很难创建实例。虽然自定义生成器应该主要依赖于反射。 (请注意,由于继承的字段,无法直接将字段放在Generator上。)