Ich landete nur mit einem Proxy. Ich dachte, ich würde es für andere veröffentlichen. Es ist nicht elegant, aber es funktioniert.
Man könnte zusätzliche Validierungsmethoden wie Sub- oder Superset-Validierung von Methoden anstelle einer exakten Übereinstimmung hinzufügen.
@Test
public void test() {
VerifyAllMethods h = new VerifyAllMethods() {
@Override
public Object runMethod(Method method, Object[] args) throws Throwable {
Class<?> rt = method.getReturnType();
if (Optional.class.equals(rt)) {
return Optional.absent();
}
else if (String.class.equals(rt)) {
return "mock";
}
else if (Integer.class.equals(rt)) {
return 1;
}
else if (List.class.equals(rt)) {
return Lists.newArrayList("1");
}
else {
return rt.newInstance();
}
}
};
SomeInterface mf = h.mock(SomeInterface.class);
// do something with SomeInterface
h.validateEquals(SomeInterface.class);
}
public abstract static class VerifyAllMethods implements InvocationHandler {
private final Set<Method> actualMethods = Sets.newLinkedHashSet();
public VerifyAllMethods() {
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
actualMethods.add(method);
return runMethod(method, args);
}
public abstract Object runMethod(Method method, Object[] args) throws Throwable;
public Set<Method> getActualMethods() {
return actualMethods;
}
public void validateEquals(Class<?> iface) {
Set<Method> methods = Sets.newHashSet(iface.getMethods());
/*
* Asserting Equals on strings is better for IDE as
* most generate a diff.
*/
assertEquals(methodsToString(methods), methodsToString(actualMethods));
}
public String methodsToString(Iterable<Method> methods) {
List<String> names = Lists.newArrayList();
for (Method m : methods) {
names.add(m.toString());
}
Collections.sort(names);
return Joiner.on("\n").join(names);
}
@SuppressWarnings("unchecked")
public <T> T mock(Class<T> iface) {
actualMethods.clear();
Class<?>[] interfaces = {iface};
return (T) Proxy.newProxyInstance(getClass().getClassLoader(), interfaces , this);
}
}
Dies scheint ein Duplikat von [dieser Frage] zu sein (http://stackoverflow.com/q/34773497/1426891). Darf ich als diple markieren? –
Ja, es scheint so :). Ich fühle mich dumm, nicht in der Lage zu sein, das zu finden. Ich kann mich zwar nicht erinnern, ob BeanInfo mit Schnittstellen arbeitet. Meine Getter-Methoden waren auch keine echten Getter, weil sie nicht mit get vorangestellt waren. –
Keine Sorge! Nicht immer leicht zu finden. Hoffentlich funktioniert die Antwort dort mit ein paar reflektiven Anpassungen an 'getMethods' anstelle von BeanInfo. –