Saltar al contenido

Cómo burlarse de una clase final con mockito

Solución:

Mockito 2 ahora es compatible con final clases y métodos!

Pero por ahora esa es una característica de “incubación”. Requiere algunos pasos para activarlo que se describen en Novedades de Mockito 2:

Burlarse de las clases y métodos finales es una incubando, función de suscripción. Utiliza una combinación de instrumentación y subclases de agentes de Java para permitir la simulación de estos tipos. Como esto funciona de manera diferente a nuestro mecanismo actual y este tiene diferentes limitaciones y como queremos recopilar experiencia y comentarios de los usuarios, esta función tenía que activarse explícitamente para estar disponible; se puede hacer a través del mecanismo de extensión mockito creando el archivo src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker que contiene una sola línea:

mock-maker-inline

Después de crear este archivo, Mockito usará automáticamente este nuevo motor y uno puede hacer:

 final class FinalClass {
   final String finalMethod() { return "something"; }
 }

 FinalClass concrete = new FinalClass(); 

 FinalClass mock = mock(FinalClass.class);
 given(mock.finalMethod()).willReturn("not anymore");

 assertThat(mock.finalMethod()).isNotEqualTo(concrete.finalMethod());

En hitos posteriores, el equipo traerá una forma programática de usar esta función. Identificaremos y brindaremos soporte para todos los escenarios inimitables. ¡Estén atentos y háganos saber lo que piensa de esta función!

La simulación de clases / métodos finales / estáticos solo es posible con Mockito v2.

agregue esto en su archivo gradle:

testImplementation 'org.mockito:mockito-inline:2.13.0'

Esto no es posible con Mockito v1, de las Preguntas frecuentes de Mockito:

Cuáles son las limitaciones de Mockito

  • Necesita Java 1.5+

  • No se puede burlar de las clases finales.

No puedes burlarte de una clase final con Mockito, ya que no puedes hacerlo tú solo.

Lo que hago es crear una clase no final para envolver la clase final y usarla como delegado. Un ejemplo de esto es TwitterFactory class, y esta es mi clase burlona:

public class TwitterFactory {

    private final twitter4j.TwitterFactory factory;

    public TwitterFactory() {
        factory = new twitter4j.TwitterFactory();
    }

    public Twitter getInstance(User user) {
        return factory.getInstance(accessToken(user));
    }

    private AccessToken accessToken(User user) {
        return new AccessToken(user.getAccessToken(), user.getAccessTokenSecret());
    }

    public Twitter getInstance() {
        return factory.getInstance();
    }
}

La desventaja es que hay mucho código repetitivo; la ventaja es que puede agregar algunos métodos que pueden relacionarse con su negocio de aplicaciones (como getInstance que toma un usuario en lugar de un accessToken, en el caso anterior).

En tu caso crearía un no final RainOnTrees clase que delega a la clase final. O, si puede hacerlo no definitivo, sería mejor.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *