2011-03-28 19 views
39

Existe un método genérico que toma una clase como parámetro y tengo problemas para anularla con Mockito. El método es el siguiente:Anulando un método que toma la clase <T> como parámetro con Mockito

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

Es espantoso, al menos para mí ... Me podía imaginar la vida sin ella, pero el resto de la base de código utiliza felizmente ...

estaba yendo a, en mi prueba unitaria, reste este método para devolver un nuevo objeto vacío. ¿Pero cómo hago esto con mockito? Probé:

pero ya que estoy mezclando y combinando comparadores y valores en bruto, me sale "org.mockito.exceptions.misusing.InvalidUseOfMatchersException: Uso no válido de comparadores de argumentos"

Respuesta

71

El problema es que no se pueden mezclar argumentos con argumento y argumentos reales en una llamada burlada. Así, en lugar de hacer esto:

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

Aviso el uso de la matcher eq() argumento a favor de la igualdad a juego.

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

Además, se podría utilizar el argumento para matcher same()Class<?> tipos - esto coincide con la identidad misma, al igual que el operador == Java.

+0

funcionó de maravilla, respuesta muy agradable. Bien explicado también –

+0

Mighty thankful! –

+0

De hecho. Pero me pregunto si Mockito podría mejorarse para permitir a los usuarios "mezclar argumentos con argumento y argumentos reales"; si Unitil Mock pudiera hacerlo, entonces debería ser técnicamente posible. –

2

Solo para completar en el mismo hilo, si alguien quiere sobrescribir un método que toma una Clase como argumento, pero no le importa el tipo, o necesita que muchos tipos se anulen de la misma manera, aquí está otra solución:

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

y luego llamar

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

uno de los buenos @Ash. Utilicé tu clasificador de clase genérico para preparar a continuación. Esto se puede utilizar si queremos preparar maqueta de un tipo específico (no ejemplo)

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

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

Uso:.

Mockito.when(restTemplate.getForObject(Mockito.anyString(), 
      **streamSourceClass(),** 
      Mockito.anyObject)); 
Cuestiones relacionadas