java - tutorial - prueba unitaria con junit
La inicialización de la clase estática no se realiza cuando se ejecuta la prueba JUnit (2)
Al final, hemos decidido usar Singleton y evitar todos los problemas con la inicialización estática. Tengo que decirle a la corporación que el problema persiste y que puede suceder nuevamente en el futuro, pero no puedo esperar a que el equipo de SQA lo arregle.
Gracias por todas sus respuestas y su tiempo
Tengo una clase de Java con algunos campos estáticos:
private static final PDMapCacheDAO REST_CACHE_DAO =
new PDMapCacheDAOImpl( Constants.REST_CACHE_NAME );
private static final PDMapCacheDAO HOLIDAYS_CACHE_DAO =
new PDMapCacheDAOImpl( Constants.HOLIDAYS_CACHE_NAME );
private static final String[] DATE_ARRAY = { "D", "0", "1", "2", "3", "C" };
y la prueba JUnit se burla de ese comportamiento de inicialización para REST_CACHE_DAO y HOLIDAYS_CACHE_DAO:
final PDMapCacheDAOImpl holidaysMapCacheDAOImpl = mock(PDMapCacheDAOImpl.class);
final PDMapCacheDAOImpl restMapCacheDAOImpl = mock(PDMapCacheDAOImpl.class);
whenNew(PDMapCacheDAOImpl.class).withArguments(Constants.HOLIDAYS_CACHE_NAME).thenReturn(holidaysMapCacheDAOImpl);
whenNew(PDMapCacheDAOImpl.class).withArguments(Constants.REST_CACHE_NAME).thenReturn(restMapCacheDAOImpl);
Cuando las pruebas se ejecutan individualmente, las pruebas funcionan como se esperaba, pero cuando todas las pruebas JUnit se ejecutan juntas (desde el Proyecto Java con Ejecutar como -> Prueba de Junit) la prueba da una excepción de puntero nulo.
He realizado algunas depuraciones y descubrí que el problema (como se indica en el título) es que las clases estáticas no se inicializan: cuando se invocan los métodos estáticos, REST_CACHE_DAO y HOLIDAYS_CACHE_DAO son nulas. El constructor de PDMapCacheDAOImpl no se invoca y los simulacros no se inyectan, por lo tanto, cuando los usamos, se obtiene un NPE.
He leído sobre algunas herramientas para realizar pruebas, como eclemma que tienen este error (algunas clases estáticas no se inicializan). En este caso, la solución es incluir la opción -f.
Esto es lo que dice el sitio web de Eclemma sobre este problema: "
2.8. ¿Cómo se define la cobertura de clase por EMMA? Antes que nada, una clase necesita ser considerada ejecutable para ser considerada para cobertura. Se considera que una clase ejecutable está cubierta si ha sido cargada e inicializada por la JVM. La inicialización de clase implica que se ejecuta el constructor estático de clase (si existe). Tenga en cuenta que una clase se puede cubrir aunque ninguno de sus otros métodos se haya ejecutado. Es común ver un pequeño número de clases cargadas pero no inicializadas cuando usa emmarun sin la opción -f. EMMA informa la cobertura de clase para que pueda detectar las clases que no parecen "tocadas" por su suite de pruebas: pueden ser código muerto o necesitan más atención de prueba.
Lo interesante es que no estamos usando Eclemma, estamos usando Cobertura, pero el comportamiento y los errores son los mismos.
¿Alguien sabe algo sobre este error en Cobertura y cómo resolverlo? (¿En Cobertura o de forma genérica)?
Esto es especulativo
Supongo que PDMapCacheDAO
es una clase de interfaz / abstracta, que usa PDMapCacheDAOImpl
para algunas constantes.
Y la clase PDMapCacheDAOImpl
implementa / extiende PDMapCacheDAO
. ¿Derecha?
Como encuentro que esta es una solución técnicamente fea (dependencias recíprocas), PDMapCacheDAOs
una interfaz separada PDMapCacheDAOs
con estas constantes.
Eso podría resolver el problema.