jupiter intellij all java junit mockito java-5

java - intellij - Mockito isA(Clase<T> clazz) ¿Cómo resolver el tipo de seguridad?



mockito-all (4)

En mi prueba tengo la siguiente línea:

when(client.runTask(anyString(), anyString(), isA(Iterable.class)).thenReturn(...)

isA(Iterable.class) produce una advertencia de que necesita una conversión sin isA(Iterable.class) para cumplir con el Iterable<Integer> . ¿Qué es la sintaxis para eso?

isA(Iterable<Integer>.class) isA((Iterable<Integer>)Iterable.class

No funcionan.

¿Alguna sugerencia?


Mockito / Hamcrest y clases genéricas.

Sí, este es un problema general con Mockito / Hamcrest. Generalmente el uso de isA() con clases genéricas produce una advertencia.

Existen emparejadores de Mockito predeterminados para las clases genéricas más comunes: anyList() , anyMap() , anySet() y anyCollection() .

Sugerencias:

anyIterable () en Mockito 2.1.0

Mockito 2.1.0 agregó un nuevo método anyIterable() para hacer coincidir Iterables:

when(client.runTask(anyString(), anyString(), anyIterable()).thenReturn(...)

Ignorar en Eclipse

Si solo quieres deshacerte de la advertencia en Eclipse. La opción existe desde Eclipse Indigo :

Ventana> Preferencias> Java> Compilador> Errores / Advertencias> Tipos genéricos> Ignorar problemas de tipo genérico inevitables

Solución rápida con @SuppressWarnings

Le sugiero que haga esto si tiene el problema una sola vez. Personalmente no recuerdo haber necesitado nunca un isA(Iterable.class) .

Como dice Daniel Pryden, puede limitar @SuppressWarnings a una variable local o un método auxiliar.

Utilice un genérico isA () matcher con TypeToken

Esto resuelve el problema para siempre. Pero tiene dos desventajas:

  • La sintaxis no es demasiado bonita y puede confundir a algunas personas.
  • Tiene una dependencia adicional de la biblioteca que proporciona la clase TypeToken . Aquí utilicé la clase TypeToken de guava . También hay una clase TypeToken en Gson y un GenericType en JAX-RS.

Usando el matcher genérico:

import static com.arendvr.matchers.InstanceOfGeneric.isA; import static org.mockito.ArgumentMatchers.argThat; // ... when(client.runTask(anyString(), anyString(), argThat(isA(new TypeToken<Iterable<Integer>>() {})))) .thenReturn(...);

Clasificadora genérica:

package com.arendvr.matchers; import com.google.common.reflect.TypeToken; import org.mockito.ArgumentMatcher; public class InstanceOfGeneric<T> implements ArgumentMatcher<T> { private final TypeToken<T> typeToken; private InstanceOfGeneric(TypeToken<T> typeToken) { this.typeToken = typeToken; } public static <T> InstanceOfGeneric<T> isA(TypeToken<T> typeToken) { return new InstanceOfGeneric<>(typeToken); } @Override public boolean matches(Object item) { return item != null && typeToken.getRawType().isAssignableFrom(item.getClass()); } }


Esto es lo que hago:

// Cast from Class<Iterable> to Class<Iterable<Integer>> via the raw type. // This is provably safe due to erasure, but will generate an unchecked warning // nonetheless, which we suppress. @SuppressWarnings("unchecked") Class<Iterable<Integer>> klass = (Class<Iterable<Integer>>) (Class) Iterable.class; // later isA(klass) // <- now this is typesafe


No hay manera de hacer esto. Para simplificar, no puede inicializar esta variable sin previo aviso:

Class<Iterable<Integer>> iterableIntegerClass = ?

Una solución podría ser usar el IntegerIterable pseudo-typedef , usted crea y usa una interfaz IntegerIterable

interface IntegerIterable extends Iterable<Integer> {}

entonces

isA(IntegerIterable.class)

no producirá más advertencia. Pero tendrá que extender la clase implementando Iterable para permitir que implementen IntegerIterable :) Por ejemplo:

public class IntegerArrayList extends ArrayList<Integer> implements IntegerIterable {}

Mmm sabroso ...

Por lo tanto, le sugeriré que considere simplemente empapelar las grietas agregando a su método:

@SuppressWarnings("unchecked")


Puede agregar @SuppressWarnings("unchecked") sobre la declaración. No hay otra forma, pero si te molesta, puedes mover el modelo a un método auxiliar.