2016-04-30 1 views
0

Lets sagen, ich habe eine Schnittstelle, die viele (wie 30) Getter wie Methoden hat.Mockito, um alle Getter wie Methoden einer Schnittstelle zu überprüfen, heißen

Ich möchte alle Methoden validiert werden ohne Angabe von jeder Methode aufgerufen (auf diese Weise, wenn die Schnittstelle aktualisiert wird, haben wir einen Fehler).

Für jetzt werde ich nur einen einfachen Java-Proxy-Handler schreiben, aber ich war neugierig, ob es eine Möglichkeit gab, dies in Mockito zu tun.

+1

Dies scheint ein Duplikat von [dieser Frage] zu sein (http://stackoverflow.com/q/34773497/1426891). Darf ich als diple markieren? –

+0

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. –

+1

Keine Sorge! Nicht immer leicht zu finden. Hoffentlich funktioniert die Antwort dort mit ein paar reflektiven Anpassungen an 'getMethods' anstelle von BeanInfo. –

Antwort

0

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); 
    } 

} 
Verwandte Themen