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" 这样深奥的东西时才会出现。对于像您这样的简单用途,一切都应该没问题。
在 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" 这样深奥的东西时才会出现。对于像您这样的简单用途,一切都应该没问题。