Tengo el siguiente registrador que quiero simular, pero para validar las entradas de registro se están llamando, no para el contenido.Mocking Logger y LoggerFactory con PowerMock y Mockito
private static Logger logger =
LoggerFactory.getLogger(GoodbyeController.class);
quiero para burlarse de cualquier clase que se utiliza para LoggerFactory.getLogger(), pero no pude encontrar la manera de hacer eso. Esto es lo que terminó con hasta ahora:
@Before
public void performBeforeEachTest() {
PowerMockito.mockStatic(LoggerFactory.class);
when(LoggerFactory.getLogger(GoodbyeController.class)).
thenReturn(loggerMock);
when(loggerMock.isDebugEnabled()).thenReturn(true);
doNothing().when(loggerMock).error(any(String.class));
...
}
me gustaría saber:
- ¿Puedo burlarse de la estática
LoggerFactory.getLogger()
a trabajar para cualquier clase? - Parece que solo puedo ejecutar
when(loggerMock.isDebugEnabled()).thenReturn(true);
en el@Before
y, por lo tanto, parece que no puedo cambiar las características por método. ¿Hay alguna forma de evitar esto? hallazgos
Editar:
pensé que ya intentado esto y no funcionó:
when(LoggerFactory.getLogger(any(Class.class))).thenReturn(loggerMock);
Pero gracias, como lo hizo el trabajo.
Sin embargo, he intentado innumerables variaciones a:
when(loggerMock.isDebugEnabled()).thenReturn(true);
no puede obtener la loggerMock a cambiar su comportamiento fuera del @Before
pero esto sólo ocurre con Coburtura. Con Clover, la cobertura muestra el 100% pero todavía hay un problema en ambos sentidos.
que tienen esta clase simple:
public ExampleService{
private static final Logger logger =
LoggerFactory.getLogger(ExampleService.class);
public String getMessage() {
if(logger.isDebugEnabled()){
logger.debug("isDebugEnabled");
logger.debug("isDebugEnabled");
}
return "Hello world!";
}
...
}
entonces tengo esta prueba:
@RunWith(PowerMockRunner.class)
@PrepareForTest({LoggerFactory.class})
public class ExampleServiceTests {
@Mock
private Logger loggerMock;
private ExampleServiceservice = new ExampleService();
@Before
public void performBeforeEachTest() {
PowerMockito.mockStatic(LoggerFactory.class);
when(LoggerFactory.getLogger(any(Class.class))).
thenReturn(loggerMock);
//PowerMockito.verifyStatic(); // fails
}
@Test
public void testIsDebugEnabled_True() throws Exception {
when(loggerMock.isDebugEnabled()).thenReturn(true);
doNothing().when(loggerMock).debug(any(String.class));
assertThat(service.getMessage(), is("Hello null: 0"));
//verify(loggerMock, atLeast(1)).isDebugEnabled(); // fails
}
@Test
public void testIsDebugEnabled_False() throws Exception {
when(loggerMock.isDebugEnabled()).thenReturn(false);
doNothing().when(loggerMock).debug(any(String.class));
assertThat(service.getMessage(), is("Hello null: 0"));
//verify(loggerMock, atLeast(1)).isDebugEnabled(); // fails
}
}
en el trébol que muestran una cobertura del 100% del bloque if(logger.isDebugEnabled()){
. Pero si intento para verificar la loggerMock
:
verify(loggerMock, atLeast(1)).isDebugEnabled();
me sale cero interacciones. También intenté PowerMockito.verifyStatic()
; en @Before
pero eso también tiene cero interacciones.
Esto parece extraño que Cobertura muestre que el if(logger.isDebugEnabled()){
no está completo al 100%, y Clover sí, pero ambos aceptan que la verificación falla.
¿Has probado @MockPolicy? [Los ejemplos aquí] (https://code.google.com/p/powermock/wiki/MockPolicies) son para simular estilos de EasyMock pero se pueden adaptar para Mockito. –