您正在构建generateRule
方法基于错误的假设,即任意的map
方法在调用时执行任何实际操作。不是这种情况。事实是map
返回另一个任意实例给出了强烈的提示。
您必须掌握的基本思想是提供者方法 - 用注释的方法@Provide
-只不过是生成过程的“描述”;它只会被调用一次。实际的对象生成随后发生并由框架控制。
这是一个重新设计的generateRule
应该做你想做的事情的方法:
@Provide
Arbitrary<Rule> generateRule() {
Arbitrary<Double> lowThresholdArb = Arbitraries.doubles()
.between(0.0, 29.0);
Arbitrary<Double> highThresholdArb = Arbitraries.doubles()
.between(30.0, 50.0);
Arbitrary<RuleConfig> configArb =
Combinators.combine(lowThresholdArb, highThresholdArb)
.as((low, high) -> {
Map<String, Object> ruleProps = new HashMap<>();
ruleProps.put(Utils.LOW_THRESHOLD, low);
ruleProps.put(Utils.HIGH_THRESHOLD, high);
RuleConfig ruleConfig = new RuleConfig();
ruleConfig.setRuleProps(ruleProps);
return ruleConfig;
});
return configArb.map(config -> {
Rule rule = new Rule();
rule.setRuleConfig(config);
return rule;
});
}
您希望看到的是,创建生成器就像数据流编程:从一些基本任意值开始 -lowThresholdArb
and highThresholdArb
- 您可以组合、映射和过滤这些内容。最后的单个实例Arbitrary
必须归还。
顺便说一句:如果您希望每次需要时都应用此生成器Rule
,你可以编写以下类:
public class RuleArbitraryProvider implements ArbitraryProvider {
@Override
public boolean canProvideFor(TypeUsage targetType) {
return targetType.isOfType(Rule.class);
}
@Override
public Set<Arbitrary<?>> provideFor(TypeUsage targetType, SubtypeProvider subtypeProvider) {
return Collections.singleton(generateRule());
}
private Arbitrary<Rule> generateRule() {
// Put here the code from above
...
}
}
and 将其注册为默认提供商 https://jqwik.net/docs/current/user-guide.html#providing-default-arbitraries.