JUnit 方法参数检查是否为 List<Person>

JUnit method parameter check if List<Person>

在 JUnit 中,我使用 ParameterResolver 动态创建方法参数并将其注入 Test,这适用于非泛型方法,例如下面期望 Person peron 的方法。我怎样才能将其更改为 List<Person> personList 并让 supportsParameter 检查 List 是否属于 Person

@ExtendWith({AnnotationProcessor.class})
public void testInject(Person person) {
    System.out.println(person);
}

AnnotationProcessor.java

@Override
public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
        throws ParameterResolutionException {
    Parameter parameter = parameterContext.getParameter();

    return Person.class.equals(parameter.getType());
}

我能使用的最接近的是:

   @Override
    public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
            throws ParameterResolutionException {
        Parameter parameter = parameterContext.getParameter();

        if (parameter.getParameterizedType()!= null && List.class.equals(parameter.getType())) {
            if (parameter.getParameterizedType() instanceof ParameterizedType) {
                ParameterizedType pt = (ParameterizedType)parameter.getParameterizedType();
                Class<?> clazz = (Class<?>)pt.getActualTypeArguments()[0];
                if (clazz == Person.class) return true;
            }


        }

        return false;
    }

这是执行您想要的操作的注释处理器。我想说你的尝试非常接近。

class AnnotationProcessor implements ParameterResolver{
    @Override
    public boolean supportsParameter(
        ParameterContext parameterContext, 
        ExtensionContext extensionContext
    ) {
        Parameter parameter = parameterContext.getParameter();

        Type type = parameter.getParameterizedType();
        if (type instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) type;
            if (!parameterizedType.getRawType().equals(List.class))
                return false;
            Type firstParameterType = parameterizedType.getActualTypeArguments()[0];
            return firstParameterType.equals(Person.class);
        }

        return false;
    }

    @Override
    public Object resolveParameter(
        ParameterContext parameterContext,
        ExtensionContext extensionContext
    ) {
        return Arrays.asList(new Person(), new Person());
    }
}

它是如何工作的?

通过反射处理注释是一项复杂的任务,因为它是事后添加到 Java 中的。这就是为什么您必须进行所有 instanceof 类型检查的原因。除此之外,它工作可靠 - 我知道,因为我在黑桃 http://jqwik.net.

中使用它

为什么有效?

在这种情况下,类型擦除不会发生,因为类型擦除只会从运行时对象中擦除类型。它不会类型声明中删除类型,例如参数和return类型。如果它做了很多图书馆用泛型类型做的有趣的事情就不会起作用了。 JDK 中存在一些关于通用类型处理和注释的错误,但它们只会在你使用像 "annotations on type parameters in innner non static classes" 这样深奥的东西时才会出现。对于像您这样的简单用途,一切都应该没问题。