I currently have a problem with Mockito. But first of all here is my code which creates the mocks Mockito complains about:
@Test
public void testRestEndpointGeneration() {
//Create a mocked classWriter to control the classWriter calls
ClassWriter classWriter = createMockedClassWriter();
//Create the list of annotated method parameters which should be used to generate the class
List<AnnotatedMethodParameter> methodParameters = new ArrayList<>();
methodParameters.add(new AnnotatedMethodParameter("testContext", "Ljavax/ws/rs/core/SecurityContext;", "Ljavax/ws/rs/core/SecurityContext;", ParameterType.CONTEXT));
methodParameters.add(new AnnotatedMethodParameter("testMatrix", "Ljava/lang/Integer;", "Ljava/lang/Integer;", ParameterType.MATRIXPARAM));
methodParameters.add(new AnnotatedMethodParameter("testForm", "Ljava/lang/Double;", "Ljava/lang/Double;", ParameterType.FORMPARAM));
RestEndpointByteCodeGenerator.createClassByteCode("EndpointGenerationTest",
"test/{testPath}",
HttpMethod.GET,
new String[]{"application/json", "application/xml"},
new String[]{"application/json", "application/xml"},
methodParameters,
new MethodParameter("Ljava/util/Map;", "Ljava/util/Map<Ljava/lang/String;Ljava/lang/Object;>;"),
classWriter);
AnnotationVisitor annotationVisitor = classWriter.visitAnnotation("", true);
FieldVisitor fieldVisitor = classWriter.visitField(1, "", "", null, null);
MethodVisitor methodVisitor = classWriter.visitMethod(1, null, null, null, null);
//Now check that the methods on the classWriter were correctly invoked
InOrder inOrder = inOrder(classWriter);
inOrder.verify(classWriter).visit(V1_7, ACC_PUBLIC + ACC_SUPER, "EndpointGenerationTest", null, "com/sportslivefinder/service/rest/generatedEndpoints/RestEndpointParent", null);
inOrder.verify(classWriter).visitAnnotation("Ljavax/ws/rs/Path;", true);
inOrder.verify(classWriter).visitField(ACC_PRIVATE + ACC_FINAL, "processor", "Lorg/apache/camel/Processor;", null, null);
inOrder.verify(classWriter).visitMethod(ACC_PUBLIC, "processRequest", "(Ljavax/ws/rs/core/SecurityContext;Ljava/lang/Integer;Ljava/lang/Double;Ljava/util/Map;)Ljavax/ws/rs/core/Response;",
"(Ljavax/ws/rs/core/SecurityContext;Ljava/lang/Integer;Ljava/lang/Double;Ljava/util/Map<Ljava/lang/String;Ljava/lang/Object;>;)Ljavax/ws/rs/core/Response;", null);
inOrder = inOrder(annotationVisitor);
inOrder.verify(annotationVisitor).visit("value", "test/{testPath}");
inOrder.verify(annotationVisitor).visitEnd();
inOrder.verify(annotationVisitor).visitEnd();
for(int i = 0; i < 1; i++){
inOrder.verify(annotationVisitor).visitArray("value");
inOrder.verify(annotationVisitor).visit(null, "application/json");
inOrder.verify(annotationVisitor).visit(null, "application/xml");
inOrder.verify(annotationVisitor).visitEnd();
inOrder.verify(annotationVisitor).visitEnd();
}
inOrder.verify(annotationVisitor).visit("value", "/");
inOrder.verify(annotationVisitor).visitEnd();
inOrder.verify(annotationVisitor).visitEnd();
inOrder.verify(annotationVisitor).visit("value", "testMatrix");
inOrder.verify(annotationVisitor).visitEnd();
inOrder.verify(annotationVisitor).visit("value", "testForm");
inOrder.verify(annotationVisitor).visitEnd();
inOrder = inOrder(fieldVisitor);
inOrder.verify(fieldVisitor).visitEnd();
inOrder = inOrder(methodVisitor);
inOrder.verify(methodVisitor).visitAnnotation("Ljavax/ws/rs/GET;", true);
inOrder.verify(methodVisitor).visitAnnotation("Ljavax/ws/rs/Produces;", true);
inOrder.verify(methodVisitor).visitAnnotation("Ljavax/ws/rs/Consumes;", true);
inOrder.verify(methodVisitor).visitAnnotation("Ljavax/ws/rs/Path;", true);
}
private ClassWriter createMockedClassWriter(){
ClassWriter classWriter = mock(ClassWriter.class);
final AnnotationVisitor annotationVisitor = createMockedAnnotationVisitor();
final MethodVisitor methodVisitor = createMockedMethodVisitor(annotationVisitor);
final FieldVisitor fieldVisitor = mock(FieldVisitor.class);
when(classWriter.visitAnnotation(anyString(), anyBoolean())).thenReturn(annotationVisitor);
doReturn(annotationVisitor).when(classWriter).visitAnnotation(anyString(), anyBoolean());
doReturn(fieldVisitor).when(classWriter).visitField(anyInt(), anyString(), anyString(), anyString(), any());
doReturn(methodVisitor).when(classWriter).visitMethod(anyInt(), anyString(), anyString(), anyString(), any(String[].class));
return classWriter;
}
private AnnotationVisitor createMockedAnnotationVisitor(){
final AnnotationVisitor visitor = mock(AnnotationVisitor.class);
doReturn(visitor).when(visitor).visitArray(anyString());
return visitor;
}
private MethodVisitor createMockedMethodVisitor(AnnotationVisitor annotationVisitor){
MethodVisitor methodVisitor = mock(MethodVisitor.class);
doReturn(annotationVisitor).when(methodVisitor).visitAnnotation(anyString(), anyBoolean());
return methodVisitor;
}
The ClassWriter and the ...Visitor classes are from asm (so if you want to test this setup you just need to import the asm, junit and mockito library). When I'm calling createMockedClassWriter() the following Exception is thrown when
when(classWriter.visitAnnotation(anyString(), anyBoolean())).thenReturn(annotationVisitor);
is called:
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Invalid use of argument matchers! 1 matchers expected, 2 recorded: -> at com.sportslivefinder.service.rest.classCreation.RestEndpointByteCodeGeneratorTest.createMockedClassWriter(RestEndpointByteCodeGeneratorTest.java:91) -> at com.sportslivefinder.service.rest.classCreation.RestEndpointByteCodeGeneratorTest.createMockedClassWriter(RestEndpointByteCodeGeneratorTest.java:91)
This exception may occur if matchers are combined with raw values: //incorrect: someMethod(anyObject(), "raw String"); When using matchers, all arguments have to be provided by matchers. For example: //correct: someMethod(anyObject(), eq("String by matcher"));
For more info see javadoc for Matchers class.
at org.objectweb.asm.ClassWriter.visitAnnotation(Unknown Source)
at com.sportslivefinder.service.rest.classCreation.RestEndpointByteCodeGeneratorTest.createMockedClassWriter(RestEndpointByteCodeGeneratorTest.java:91)
at com.sportslivefinder.service.rest.classCreation.RestEndpointByteCodeGeneratorTest.testRestEndpointGeneration(RestEndpointByteCodeGeneratorTest.java:28)
As you can see, I've tried different styles of the stub creation but this seems not the problem.
Can anybody help me out here?
Greetings, Pascal