junit-quickcheck:如何以惯用的方式编写生成器

时间:2017-07-25 07:10:30

标签: java junit quickcheck

junit-quickcheck编写生成器时,可以轻松使用提供的CtorFields反射方法。但直接在我的业务模型上应用反射可以防止我限制生成的数据(除非我将业务模型与快速检查注释交错)。

例如:

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上。)

0 个答案:

没有答案