2011-03-28 10 views
39

Esiste un metodo generico che accetta una classe come parametro e ho problemi a eseguirla con Mockito. Il metodo è simile al seguente:Stubazione di un metodo che utilizza la classe <T> come parametro con Mockito

public <U extends Enum<U> & Error, T extends ServiceResponse<U>> T validate(
    Object target, Validator validator, Class<T> responseClass, 
    Class<U> errorEnum); 

E 'dio terribile, almeno per me ... Potrei immaginare di vivere senza di esso, ma il resto del codice di base felicemente lo usa ...

ero andando a, nel mio test di unità, stub questo metodo per restituire un nuovo oggetto vuoto. Ma come faccio a farlo con il mockito? Ho provato:

ma dato che sono miscelazione e la congruenza matchers e valori grezzi, ottengo "org.mockito.exceptions.misusing.InvalidUseOfMatchersException: utilizzo non valido di matchers argomento"

risposta

71

Il problema è che non è possibile combinare gli argomenti di confronto e gli argomenti reali in una chiamata derisoria. Quindi, piuttosto fare questo:

when(serviceValidatorStub.validate(
    any(), 
    isA(UserCommentRequestValidator.class), 
    eq(UserCommentResponse.class), 
    eq(UserCommentError.class)) 
).thenReturn(new UserCommentResponse()); 

Si noti l'uso del matcher eq() argomento per corrispondenza uguaglianza.

vedere: https://static.javadoc.io/org.mockito/mockito-core/1.10.19/org/mockito/Matchers.html#eq(T)

Inoltre, è possibile utilizzare il matcher same() argomento per Class<?> tipi - questo corrisponde stessa identità, come l'operatore == Java.

+0

lavorato come un fascino, risposta molto bello. Ben spiegato anche –

+0

Mighty thankful! –

+0

Infatti. Ma mi chiedo se Mockito potrebbe essere migliorato per consentire agli utenti di "combinare argomenti matchers e argomenti reali"; se Unitils Mock potesse farlo, dovrebbe essere tecnicamente possibile. –

2

Al fine di completare sullo stesso thread, se qualcuno desidera eseguire un metodo di stub che accetta una classe come argomento, ma non si cura del tipo, o ha bisogno di molti tipi per eseguire lo stub allo stesso modo, ecco un'altra soluzione:

private class AnyClassMatcher extends ArgumentMatcher<Class<?>> { 

    @Override 
    public boolean matches(final Object argument) { 
     // We always return true, because we want to acknowledge all class types 
     return true; 
    } 

} 

private Class<?> anyClass() { 
    return Mockito.argThat(new AnyClassMatcher()); 
} 

e quindi chiamare

Mockito.when(mock.doIt(this.anyClass())).thenCallRealMethod(); 
0

Nice one @Ash. Ho usato il tuo compagno di classe generico per preparare di seguito. Questo può essere usato se vogliamo preparare finta di un tipo specifico (non esempio)

private Class<StreamSource> streamSourceClass() { 
    return Mockito.argThat(new ArgumentMatcher<Class<StreamSource>>() { 

     @Override 
     public boolean matches(Object argument) { 
      // TODO Auto-generated method stub 
      return false; 
     } 
    }); 
} 

Usage:.

Mockito.when(restTemplate.getForObject(Mockito.anyString(), 
      **streamSourceClass(),** 
      Mockito.anyObject)); 
Problemi correlati