unitarias unitaria tutorial test pruebas prueba español ejemplos ejemplo create con java junit slf4j logback

java - unitaria - ¿Cómo interceptar el registro SLF4J a través de una prueba JUnit?



pruebas unitarias (3)

Puede crear un appender personalizado

public class TestAppender extends AppenderBase<LoggingEvent> { static List<LoggingEvent> events = new ArrayList<>(); @Override protected void append(LoggingEvent e) { events.add(e); } }

y configure logback-test.xml para usarlo. Ahora podemos verificar los eventos de registro de nuestra prueba:

@Test public void test() { ... Assert.assertEquals(1, TestAppender.events.size()); ... }

¿Es posible de alguna manera interceptar el registro (SLF4J + logback) y obtener un InputStream (u otra cosa que sea legible) a través de un caso de prueba JUnit ...?


Puede usar slf4j-test desde http://projects.lidalia.org.uk/slf4j-test/ . Reemplaza toda la implementación logback slf4j por su propia implementación slf4j api para pruebas y proporciona una API para afirmar contra eventos de registro.

ejemplo:

<build> <plugins> <plugin> <artifactId>maven-surefire-plugin</artifactId> <configuration> <classpathDependencyExcludes> <classpathDependencyExcludes>ch.qos.logback:logback-classic</classpathDependencyExcludes> </classpathDependencyExcludes> </configuration> </plugin> </plugins> </build> public class Slf4jUser { private static final Logger logger = LoggerFactory.getLogger(Slf4jUser.class); public void aMethodThatLogs() { logger.info("Hello World!"); } } public class Slf4jUserTest { Slf4jUser slf4jUser = new Slf4jUser(); TestLogger logger = TestLoggerFactory.getTestLogger(Slf4jUser.class); @Test public void aMethodThatLogsLogsAsExpected() { slf4jUser.aMethodThatLogs(); assertThat(logger.getLoggingEvents(), is(asList(info("Hello World!")))); } @After public void clearLoggers() { TestLoggerFactory.clear(); } }


Tuve problemas al probar registros de línea como: LOGGER.error (mensaje, excepción) .

La solución descrita en http://projects.lidalia.org.uk/slf4j-test/ intenta afirmar también en la excepción y no es fácil (y en mi opinión no tiene ningún valor) para recrear la stacktrace.

Lo resolví de esta manera:

import org.junit.Test; import org.slf4j.Logger; import uk.org.lidalia.slf4jext.LoggerFactory; import uk.org.lidalia.slf4jtest.TestLogger; import uk.org.lidalia.slf4jtest.TestLoggerFactory; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.groups.Tuple.tuple; import static uk.org.lidalia.slf4jext.Level.ERROR; import static uk.org.lidalia.slf4jext.Level.INFO; public class Slf4jLoggerTest { private static final Logger LOGGER = LoggerFactory.getLogger(Slf4jLoggerTest.class); private void methodUnderTestInSomeClassInProductionCode() { LOGGER.info("info message"); LOGGER.error("error message"); LOGGER.error("error message with exception", new RuntimeException("this part is not tested")); } private static final TestLogger TEST_LOGGER = TestLoggerFactory.getTestLogger(Slf4jLoggerTest.class); @Test public void testForMethod() throws Exception { // when methodUnderTestInSomeClassInProductionCode(); // then assertThat(TEST_LOGGER.getLoggingEvents()).extracting("level", "message").contains( tuple(INFO, "info message"), tuple(ERROR, "error message"), tuple(ERROR, "error message with exception") ); } }

Esto también tiene la ventaja de no tener que depender de la biblioteca Hamcrest Matchers .