使用jqwik.net,尝试生成其中包含嵌套RuleConfig类的Rule类。RuleConfig类具有一个嵌套的ruleProps,它是一个Map
statusReturnedFromApplyingRule方法始终返回初始化的规则,而不是使用@provide方法的值?返回的规则:rule:Rule{ruleId='null', inputMetricSelector=null, ruleConfig='RuleConfig{ruleType='null', ruleProps={}}'}, elements:[{}]
这是我的代码:
public class RangeMatchRuleTest {
@Property
@Report(Reporting.GENERATED)
boolean statusReturnedFromApplyingRule(@ForAll("generateRule") Rule rule,
@ForAll("generateInputMapElements") Iterable<Map<String, Object>> elements) {
RangeMatchRule rangeMatchRule = new RangeMatchRule();
final RuleIF.Status status = rangeMatchRule.applyRule(rule, elements);
return RuleIF.getEnums().contains(status.toString());
}
@Provide
Arbitrary<Rule> generateRule() {
Rule rule = new Rule();
RuleConfig ruleConfig = new RuleConfig();
Map<String, Object> ruleProps = new HashMap<>();
Arbitrary<Double> lowThresholdArb = Arbitraries.doubles()
.between(0.0, 29.0);
lowThresholdArb.allValues().ifPresent(doubleStream -> ruleProps.put(Utils.LOW_THRESHOLD, doubleStream.findFirst().get()));
//lowThresholdArb.map(lowThreshold -> ruleProps.put(Utils.LOW_THRESHOLD, lowThreshold) );
Arbitrary<Double> highThresholdArb = Arbitraries.doubles()
.between(30.0, 50.0);
highThresholdArb.map(highThreshold -> ruleProps.put(Utils.HIGH_THRESHOLD, highThreshold));
ruleConfig.setRuleProps(ruleProps);
rule.setRuleConfig(ruleConfig);
return Arbitraries.create(() -> rule);
}
@Provide
Arbitrary<Iterable<Map<String, Object>>> generateInputMapElements() {
Arbitrary<Double> metricValueArb = Arbitraries.doubles()
.between(0, 50.0);
Map<String, Object> inputMap = new HashMap<>();
metricValueArb.map(metricValue -> inputMap.put(Utils.METRIC_VALUE, metricValue));
List<Map<String, Object>> inputMapLst = new ArrayList<>();
inputMapLst.add(inputMap);
return Arbitraries.create(() -> inputMapLst);
}
}
TIA
您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
然后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
...
}
}
并将其注册为默认提供程序。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句