I have the following situation:
I want to attach an Answer
to every method call of a specific class instance. So for example with the class
public class Example {
public int example1() { /* */ }
public int example2(Object a) { /* */ }
public int example3(Object a, Integer b) { /* */ }
public int example4(int a) { /* */ }
}
I want to do the following
public Example attachToExample(Example ex) {
Example spy = Mockito.spy(ex);
Answer<Object> answer = /* */;
doAnswer(answer).when(spy).example1();
doAnswer(answer).when(spy).example2(any());
doAnswer(answer).when(spy).example3(any(), any());
doAnswer(answer).when(spy).example4(anyInt());
return spy;
}
This works but what I would like to do is generalize this to not just Example
instances but arbitrary Objects.
So what I would like to do is
public Object attachToExample(Object o) {
Object spy = Mockito.spy(o);
Answer<Object> answer = /* */;
for(Method m : o.getClass().getMethods()) {
/* skipping methods that cannot be mocked (equals/hashCode/final/..) */
doAnswer(answer).when(spy)./* Method m with according arguments */;
}
return spy;
}
What I would need to do for that is construct argument matchers any
/anyInt
/.. depending on the amount of parameters of each method and their types (primitive/non primitive). Ideally I would create a list of arguments like this:
Class<?>[] params = m.getParameterTypes();
ArrayList<Object> args = new ArrayList<>();
for (Class<?> param : params) {
if ("int".equals(param.toString())) {
args.add(ArgumentMatchers.anyInt());
} else { // Cases for other primitive types left out.
args.add(ArgumentMatchers.any()); // Found non primitive. We can use 'any()'
}
}
try {
doAnswer(answer).when(spy).getClass().getMethod(m.getName(), m.getParameterTypes())
.invoke(spy, args.toArray());
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
e.printStackTrace();
}
This does not work as using argument matchers outside of stubbing is not supported but I hope that this makes clear what I want to do.
Is there any way to make this work or is there a different way of archiving what I want to do?
Aucun commentaire:
Enregistrer un commentaire