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

vmpqdwk3  于 2023-05-12  发布在  Java
关注(0)|答案(1)|浏览(194)

在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;
    }
c3frrgcw

c3frrgcw1#

下面是注解处理器,它可以完成您想要的任务。我得说你的企图很接近了。

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类型检查的原因。除此之外,它工作可靠。

为什么可以?

类型擦除在这种情况下不会发生,因为类型擦除只擦除运行时对象中的类型。它不会从类型声明中删除类型,比如参数和返回类型。如果它做了许多库对泛型类型所做的有趣的事情,就不会工作了。JDK中有一些关于泛型类型处理和注解的bug,但是只有当你去找一些深奥的东西,比如“内部非静态类中类型参数的注解”时,它们才会让你明白。对于像你这样简单的用途,一切都应该很好。

相关问题