Inicio > Java > Powermockito. Whitebox y llamado de constructores privados.

Powermockito. Whitebox y llamado de constructores privados.

Haciendo unos tests Unitarios, el otro día me ví confrontado a deber inicializar un objeto que no podía instanciar, ya que su constructor era privado. No recuerdo el contexto en el que me encontraba para haber llegado a esta situacion, pero lo que retuve en este ejercicio es que existe un API que nos permite utilizar los constructores privados gracias a la reflexión: PowerMockito.

Para explicar la utilización de PowerMockito, supongamos que he creado mi propia clase que representa una Map. El objetivo principal de ésta implementación es de recuperar la clave a partir de un valor. El mismo principio del get(Object) de Map, pero al revés.

diagram

En mi clase, además, un objeto no se puede instanciar porque el constructor es privado. Sin embargo, un MyMaps se obtiene via el método estático create.

public static <K, V> MyMaps<K, V> create(Map<K, V> map) {
_____return new MyMaps(map.keySet(), map.values());
}

private MyMaps(Set<K> keys, Collection<V> values) {
_____if ( keys.size() == values.size() ) {
__________size = keys.size();
__________myKeys = new ArrayList<K>(keys);
__________myValues = new ArrayList<V>(values);
_____}
}

A grandes rasgos, cuando se crea un objeto MyMaps, la Map que se le pasa en parámetro es dividida en una lista para las claves, y una para los valores. No vamos a discutir si esta representación es lógica, óptima o útil. Simplemente vamos a usarla para explicar el uso de PowerMockito.

Dentro de las clases que propone PowerMockito, tenemmos WhiteBox que permite la utilización de la reflexión en los test Unitarios. Dos métodos

permiten el llamado de métodos, en este caso, el método privado. Teniendo esto, podemos ver el código para obtener un objeto MyMaps via create y otro via WhiteBox:

Map hashMap = new HashMap<Book, Author>();
hashMap.put(author1, book1);
hashMap.put(author2, book2);

MyMaps<Book, Author> createdMap = MyMaps.create(hashMap);

MyMaps<Book, Author> privateConstructorMap = Whitebox.invokeConstructor(MyMaps.class,
_______________________new Class<?>[]{Set.class, Collection.class},
_______________________new Object[]{hashMap.keySet(), hashMap.values()});

Para ver el código completo del ejemplo utilizado, hacer clic acá (branch powermockito del proyecto). De la misma manera que llamamos un constructor usando la reflexión, otros métodos pueden ser explotados (ver invokeMethod).

Para incluir PowerMockito en las dependencias de un proyecto, agregar esto al pom:

<dependency>
___<groupId>org.powermock</groupId>
___<artifactId>powermock-api-mockito</artifactId>
___<scope>test</scope>
</dependency>
<dependency>
___<groupId>org.powermock</groupId>
___<artifactId>powermock-module-junit4</artifactId>
___<!-- para testng <artifactId>powermock-module-testng</artifactId>-->
___<scope>test</scope>
</dependency>

  1. Aún no hay comentarios.
  1. No trackbacks yet.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

Hype Driven Development

coz' geeks love new stuff !

My experiments with SCRUM

Site to discuss Agile (Scrum, XP, etc) concepts and ideas.

CommitStrip

Mi propia cheatsheet...

Chris Aniszczyk's (zx) diatribe

work. life. open source. diatribes.

GermanTrevi

repositorio de mi mente...

A %d blogueros les gusta esto: