Påstand om logmeddelelser med JUnit

1. Introduktion

I denne vejledning ser vi på, hvordan vi kan dække genererede logfiler i JUnit-test.

Vi bruger slf4j-api og logbackimplementering og oprette en brugerdefineret appender, som vi kan bruge til logpåstand.

2. Maven-afhængigheder

Før vi begynder, lad os tilføje logback afhængighed. Som det indfødt implementerer slf4j-api, det downloades automatisk og injiceres i projektet af Maven transitivity:

 ch.qos.logback logback-classic. 1.2.3 

AssertJ tilbyder meget nyttige funktioner under testning, så lad os også tilføje dens afhængighed til projektet:

 org.assertj assertj-core 3.15.0 test 

3. En grundlæggende forretningsfunktion

Lad os nu oprette et objekt, der genererer logfiler, som vi kan basere vores test på.

Vores Forretningsarbejder objekt eksponerer kun en metode. Denne metode genererer en log med det samme indhold for hvert logniveau. Selvom denne metode ikke er så nyttig i den virkelige verden, vil den tjene godt til vores testformål:

offentlig klasse BusinessWorker {privat statisk logger LOGGER = LoggerFactory.getLogger (BusinessWorker.class); offentligt ugyldigt generereLogs (String msg) {LOGGER.trace (msg); LOGGER.debug (msg); LOGGER.info (msg); LOGGER.warn (msg); LOGGER.error (msg); }}

4. Test af logfiler

Vi vil generere logfiler, så lad os oprette en logback.xml fil i src / test / ressourcer folder. Lad os holde det så simpelt som muligt og omdirigere alle logfiler til en KONSOL appender:

     % d {HH: mm: ss.SSS} [% t]% -5niveau% logger {36} -% msg% n 

4.1. MemoryAppender

Lad os nu oprette en brugerdefineret appender, der holder logfiler i hukommelsen. Godt udvide ListAppender at logback tilbud, og vi beriger det med et par nyttige metoder:

offentlig klasse MemoryAppender udvider ListAppender {offentlig nulstillet nulstilling () {this.list.clear (); } offentlig boolsk indeholder (strengstreng, niveauniveau) {returner this.list.stream () .anyMatch (event -> event.getMessage (). toString (). indeholder (string) && event.getLevel (). lig med (niveau )); } public int countEventsForLogger (String loggerName) {return (int) this.list.stream () .filter (event -> event.getLoggerName (). indeholder (loggerName)) .count (); } offentlig liste søgning (strengstreng) {returner denne.liste.strøm () .filter (begivenhed -> begivenhed.getMessage (). tilString (). indeholder (streng)). indsamling (Collectors.toList ()); } offentlig liste søgning (strengstreng, niveau niveau) {returner this.list.stream () .filter (event -> event.getMessage (). toString (). indeholder (string) && event.getLevel (). lig med (niveau )) .collect (Collectors.toList ()); } public int getSize () {returner this.list.size (); } offentlig liste getLoggedEvents () {returner Collections.unmodifiableList (this.list); }}

Det MemoryAppender klasse håndterer en Liste der automatisk udfyldes af logningssystemet.

Det udsætter en række forskellige metoder for at dække en bred vifte af testformål:

  • Nulstil() - rydder listen
  • indeholder (msg, niveau) - vender tilbage rigtigt kun hvis listen indeholder en ILoggingEvent matcher det specificerede indhold og sværhedsgrad
  • countEventForLoggers (loggerName) - returnerer antallet af ILoggingEvent genereret af navngivet logger
  • søg (msg) - returnerer a Liste af ILoggingEvent matcher det specifikke indhold
  • søg (msg, niveau) - returnerer a Liste af ILoggingEvent matcher det specificerede indhold og sværhedsgrad
  • getSize () - returnerer antallet af ILoggingEvents
  • getLoggedEvents () - returnerer et umodificerbart syn på ILoggingEvent elementer

4.2. Enhedstest

Lad os derefter oprette en JUnit-test til vores forretningsmedarbejder.

Vi erklærer vores MemoryAppender som et felt og indsprøjte det programmelt i logsystemet. Derefter starter vi appenderen.

Til vores tests indstiller vi niveauet til FEJLFINDE:

@Før offentlig tomrumsopsætning () {Logger logger = (Logger) LoggerFactory.getLogger (LOGGER_NAME); memoryAppender = ny MemoryAppender (); memoryAppender.setContext ((LoggerContext) LoggerFactory.getILoggerFactory ()); logger.setLevel (Niveau.DEBUG); logger.addAppender (memoryAppender); memoryAppender.start (); }

Nu kan vi oprette en simpel test, hvor vi instantierer vores Forretningsarbejder klasse og kalde createLogs metode. Vi kan derefter komme med påstande om de logfiler, den genererer:

@Test offentlig ugyldighedstest () {BusinessWorker-medarbejder = ny BusinessWorker (); worker.generateLogs (MSG); assertThat (memoryAppender.countEventsForLogger (LOGGER_NAME)). er EqualTo (4); assertThat (memoryAppender.search (MSG, Level.INFO) .størrelse ()). erEqualTo (1); assertThat (memoryAppender.contains (MSG, Level.TRACE)). isFalse (); }

Denne test bruger tre funktioner i MemoryAppender:

  • Fire logfiler er genereret - en post pr. Sværhedsgrad skal være til stede med sporingsniveauet filtreret
  • Kun en logpost med indholdet besked med niveauet sværhedsgrad af INFO
  • Ingen logindlæg er til stede med indhold besked og sværhedsgrad SPOR

Hvis vi planlægger at bruge den samme forekomst af denne klasse i den samme testklasse, når vi genererer mange logfiler, kryber hukommelsesforbruget op. Vi kan påberåbe os MemoryAppender.clear () metode før hver test for at frigøre hukommelse og undgå OutOfMemoryException.

I dette eksempel har vi reduceret omfanget af de lagrede logfiler til LOGGER_NAME pakke, som vi definerede som “com.baeldung.junit.log“. Vi kan potentielt beholde alle logfiler med LoggerFactory.getLogger (Logger.ROOT_LOGGER_NAME), men vi bør undgå dette, når det er muligt, da det kan forbruge en masse hukommelse.

5. Konklusion

Med denne vejledning har vi demonstreret hvordan man dækker loggenerering i vores enhedstest.

Som altid kan koden findes på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found