如何向@Provide传递参数?jqwik属性测试Provider参数化问题
问题核心原因
自定义注解无法被识别通常有两个常见原因:
- 自定义注解未添加
@Retention(RetentionPolicy.RUNTIME)元注解,JVM会在运行期丢弃没有保留策略配置的注解,导致TypeUsage无法读取 - Provider方法没有注入
TypeUsage参数来获取参数上挂载的所有注解
解决方案1:使用自定义注解实现
第一步:修正自定义@Length注解定义
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) public @interface Length { int min(); int max(); }
第二步:调整Provider方法读取注解参数
import net.jqwik.api.Arbitraries; import net.jqwik.api.Arbitrary; import net.jqwik.api.Provide; import net.jqwik.api.type.TypeUsage; @Provide Arbitrary<CharSequence> charSequence(TypeUsage typeUsage) { Length lengthConfig = typeUsage.findAnnotation(Length.class) .orElseThrow(() -> new IllegalArgumentException("需要为CharSequence参数配置@Length注解")); int minLength = lengthConfig.min(); int maxLength = lengthConfig.max(); Arbitrary<String> stringArbitrary = Arbitraries.strings() .ofMinLength(minLength) .ofMaxLength(maxLength) .injectNull(0.01); Arbitrary<StringBuffer> stringBufferArbitrary = stringArbitrary.map(str -> null == str ? null : new StringBuffer(str)); Arbitrary<StringBuilder> stringBuilderArbitrary = stringArbitrary.map(str -> null == str ? null : new StringBuilder(str)); return Arbitraries.oneOf(stringArbitrary, stringBufferArbitrary, stringBuilderArbitrary); }
第三步:测试方法使用方式
import net.jqwik.api.ForAll; import net.jqwik.api.Property; @Property void test(@ForAll("charSequence") @Length(min = 2, max = 5) CharSequence cs) { // 你的测试逻辑 }
解决方案2:使用原生@ForAll attributes传参(无需自定义注解)
如果你不想额外维护自定义注解,也可以直接用jqwik原生的参数传递能力:
// 测试方法 @Property void test(@ForAll(value = "charSequence", attributes = {"2", "5"}) CharSequence cs) { // 测试逻辑 } // Provider方法 @Provide Arbitrary<CharSequence> charSequence(String[] attributes) { int minLength = Integer.parseInt(attributes[0]); int maxLength = Integer.parseInt(attributes[1]); // 生成逻辑和上面完全一致 }
内容的提问来源于stack exchange,提问作者Leponzo
相关产品推荐
相关产品推荐

