我正在编写Rest API,我的自动化测试直接调用该类而不部署到服务器。举个例子,我正在测试这个方法:
@GET
@Path("/{referenceId}")
@Produces("application/json")
public String findByReferenceId(@PathParam("referenceId") String referenceId,
String view) {
我的测试是检查逻辑是否有效并且它们通过了。但是这段代码有一个错误:我忘了在@QueryParam
参数上添加view
注释。因此,此代码在测试时有效,但如果您尝试在已部署的应用程序上使用此资源,则view
参数将永远不可设置。
我有很多方法可以解决这个问题,但我目前的偏好是以某种方式编写一个自动检查,如果方法有@Path
注释,那么每个参数都必须有@PathParam
, @QueryParam
或其他任何有效的注释都可以存在。
我更喜欢这种新的端到端测试,因为我的其他测试已经覆盖了95%的逻辑。我只是不知道如何自动执行此检查。我正在使用Maven和CXF(这意味着我正在使用Spring)。我希望有一个插件可以配置为执行此操作。
我刚刚意识到的东西:没有注释的单个参数是有效的。当你这样做时,jax-rs将它设置为你传入的实体。我不知道如何处理这种情况。我可以创建自己的自定义注释@Payload
并告诉人们使用它,但有些事情似乎是错误的。
答案 0 :(得分:1)
这是我的解决方案。最后,我决定创建一个@RawPayload
注释。否则,我无法知道缺失的注释是否是有意的。这是我获得Reflections
课程的地方:https://code.google.com/p/reflections/
import org.junit.Test;
import org.reflections.Reflections;
import org.reflections.scanners.MethodAnnotationsScanner;
import javax.ws.rs.Path;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Set;
import static org.junit.Assert.assertTrue;
...
@Test
public void testAllParametersAreAnnotated() throws Exception {
String message = "You are missing a jax-rs annotation on a method's parameter: ";
Reflections reflections = new Reflections("package.for.my.services", new MethodAnnotationsScanner());
Set<Method> resourceMethods = reflections.getMethodsAnnotatedWith(Path.class);
assertTrue(resourceMethods.size() > 0);
for (Method resourceMethod : resourceMethods) {
for (int i = 0; i < resourceMethod.getGenericParameterTypes().length; i++) {
Annotation[] annotations = resourceMethod.getParameterAnnotations()[i];
boolean annotationExists = annotations.length > 0;
assertTrue(message +
resourceMethod.getDeclaringClass().getCanonicalName() +
"#" +
resourceMethod.getName(),
annotationExists && containsJaxRsAnnotation(annotations));
}
}
}
private boolean containsJaxRsAnnotation(Annotation[] annotations) {
for (Annotation annotation : annotations) {
if (annotation instanceof RawPayload) {
return true;
}
if (annotation.annotationType().getCanonicalName().startsWith("javax.ws.rs")) {
return true;
}
}
return false;
}
这是我的注释:
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* I'm creating this marker so that we can put it on raw payload params. This is normally unnecessary,
* but it lets me write a very useful automated test.
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface RawPayload {
}