junit自定义ArgumentsSource以自定义ParameterizedTest参数加载方式

junit提供了ArgumentsSource注解以便于用户自定义ParameterizedTestt参数加载方式

直接上代码

核心代码

kotlin 复制代码
import cn.hutool.core.io.resource.ResourceUtil
import org.junit.jupiter.api.extension.ExtensionContext
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.AnnotationBasedArgumentsProvider
import org.junit.jupiter.params.provider.Arguments
import org.junit.jupiter.params.provider.ArgumentsSource
import org.junit.jupiter.params.support.ParameterDeclarations
import java.nio.charset.StandardCharsets
import java.util.stream.Stream


@Target(AnnotationTarget.FUNCTION) //简单的只允许放在测试方法上
@MustBeDocumented
@Retention
@ParameterizedTest //这样就不需在用例上加上这个注解了
@ArgumentsSource(YamlAnnotationBasedArgumentsProvider::class)
annotation class MyYamlSource(
    val value: Array<String>
)
class YamlAnnotationBasedArgumentsProvider: AnnotationBasedArgumentsProvider<MyYamlSource>() {
    override fun provideArguments(
        parameters: ParameterDeclarations,
        context: ExtensionContext,
        source: MyYamlSource
    ): Stream<out Arguments?> {
        //读取每一个配置
        return source.value.map {
            var s = it
            //当配置以后缀结尾则读取文件,否则配置文本就是yaml
            if(s.endsWith(".yaml")||s.endsWith(".yml")) {
                s = ResourceUtil.readStr(s, StandardCharsets.UTF_8)
            }
            val yaml = MyUtil.YAML.load<LinkedHashMap<String, Any>>(s)
            val args = parameters.all.map {
                var pv = yaml.getOrDefault(it.parameterIndex.toString(),null)
                if (pv!=null && !pv::class.java.isAssignableFrom(it.parameterType)){
                    pv = MyUtil.JSON_MAPPER.convertValue(pv,it.parameterType)
                }
                return@map pv
            }.toTypedArray()
            //包装后返回流
            return@map Arguments.of(*args)
        }.stream()
    }
}

所需的工具类

kotlin 复制代码
import org.yaml.snakeyaml.LoaderOptions
import org.yaml.snakeyaml.Yaml
import org.yaml.snakeyaml.constructor.Constructor
import org.yaml.snakeyaml.inspector.TagInspector
import tools.jackson.core.json.JsonReadFeature
import tools.jackson.databind.json.JsonMapper
import tools.jackson.databind.jsontype.BasicPolymorphicTypeValidator
import java.text.SimpleDateFormat
import java.util.*

object MyUtil {
    @JvmField
    val JSON_PTV: BasicPolymorphicTypeValidator = BasicPolymorphicTypeValidator.builder()
        .allowIfSubType("local.demo_sb4")
        .build()
    @JvmField
    val JSON_MAPPER: JsonMapper = JsonMapper.builder()
        .polymorphicTypeValidator(JSON_PTV)
        .apply {
            defaultDateFormat(SimpleDateFormat("yyyy-MM-dd HH:mm:ss"))
            defaultLocale(Locale.CHINA)
            defaultTimeZone(TimeZone.getTimeZone("GMT+8"))
        }
        .apply {
            for (feature in JsonReadFeature.entries) {
                if(feature.name.startsWith("ALLOW"))
                    configure(feature, true)
            }
        }
        .build()
    val YAML: Yaml = Yaml(Constructor(LoaderOptions().also {
        it.tagInspector = TagInspector { true }
    }))
}

运行测试

java 复制代码
public class MyTest {
    public static class Obj {
        public String name;
    }
    @MyYamlSource({"test1.yml"})
    public void test1(Obj o){
        System.out.println(o.name);
    }
}
/*
输出:
> Task :testClasses
测试
> Task :test
*/
相关推荐
金銀銅鐵5 天前
浅解 JUnit 4 第九篇:JUnitCore (下)
junit·单元测试
钟智强5 天前
CVE-2025-49844高危预警:Redis Lua脚本引擎UAF漏洞深度剖析与POC实战
数据库·redis·web安全·junit·lua
金銀銅鐵5 天前
浅解 JUnit 4 第八篇:JUnitCore (上)
junit·单元测试
百锦再7 天前
Java中的日期时间API详解:从Date、Calendar到现代时间体系
java·开发语言·spring boot·struts·spring cloud·junit·kafka
金銀銅鐵9 天前
浅解 Junit 4 第七篇:AllDefaultPossibilitiesBuilder
java·junit·单元测试
金銀銅鐵10 天前
浅解 Junit 4 第六篇:AnnotatedBuilder 和 RunnerBuilder
后端·junit·单元测试
金銀銅鐵10 天前
浅解 Junit 4 第五篇:IgnoredBuilder 和 RunnerBuilder
junit·单元测试
金銀銅鐵14 天前
浅解 Junit 4 第四篇:类上的 @Ignore 注解
java·junit·单元测试
金銀銅鐵14 天前
浅解 Junit 4 第二篇: Runner 和 ParentRunner
java·junit·单元测试
金銀銅鐵14 天前
浅解 Junit 4 第三篇:Suite
junit·单元测试