Påstå loggmeldinger med JUnit

1. Introduksjon

I denne opplæringen vil vi se på hvordan vi kan dekke genererte logger i JUnit-testing.

Vi bruker slf4j-api og tilbakekoblinggjennomføring og skape en tilpasset appender som vi kan bruke til påstand om logg.

2. Maven-avhengigheter

La oss legge til før vi begynner tilbakekobling avhengighet. Som den innfødte implementerer slf4j-apiblir den automatisk lastet ned og injisert i prosjektet av Maven transitivity:

 ch.qos.logback logback-classic. 1.2.3 

AssertJ tilbyr veldig nyttige funksjoner når du tester, så la oss også legge til dens avhengighet i prosjektet:

 org.assertj assertj-core 3.15.0 test 

3. En grunnleggende forretningsfunksjon

La oss nå lage et objekt som vil generere logger vi kan basere testene våre på.

Våre BusinessWorker objektet vil bare avsløre en metode. Denne metoden vil generere en logg med samme innhold for hvert loggnivå. Selv om denne metoden ikke er så nyttig i den virkelige verden, vil den tjene godt for våre testformål:

offentlig klasse BusinessWorker {private static Logger LOGGER = LoggerFactory.getLogger (BusinessWorker.class); offentlig ugyldig generereLogger (streng msg) {LOGGER.trace (msg); LOGGER.debug (msg); LOGGER.info (msg); LOGGER.warn (msg); LOGGER.error (msg); }}

4. Testing av loggene

Vi vil generere logger, så la oss lage en logback.xml filen i src / test / ressurser mappe. La oss holde det så enkelt som mulig og omdirigere alle loggene til en KONSOLL appender:

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

4.1. MemoryAppender

La oss nå lage en tilpasset appender som holder logger i minnet. Vi vil utvide ListAppender at tilbakekobling tilbud, og vi beriker det med noen nyttige metoder:

offentlig klasse MemoryAppender utvider ListAppender {public void reset () {this.list.clear (); } public boolean inneholder (strengstreng, nivånivå) {returner this.list.stream () .anyMatch (event -> event.getMessage (). toString (). inneholder (string) && event.getLevel (). er lik (nivå )); } public int countEventsForLogger (String loggerName) {return (int) this.list.stream () .filter (event -> event.getLoggerName (). contains (loggerName)) .count (); } offentlig listesøk (strengstreng) {returner this.list.stream () .filter (event -> event.getMessage (). toString (). inneholder (string)) .collect (Collectors.toList ()); } offentlig listesøk (strengstreng, nivånivå) {returner this.list.stream () .filter (event -> event.getMessage (). toString (). inneholder (string) && event.getLevel (). er lik (nivå )) .collect (Collectors.toList ()); } public int getSize () {return this.list.size (); } offentlig liste getLoggedEvents () {return Collections.unmodifiableList (this.list); }}

De MemoryAppender klasse håndterer a Liste som automatisk fylles ut av loggesystemet.

Den avslører en rekke metoder for å dekke et bredt spekter av testformål:

  • nullstille() - tømmer listen
  • inneholder (msg, level) - kommer tilbake ekte bare hvis listen inneholder et ILoggingEvent samsvarer med spesifisert innhold og alvorlighetsgrad
  • countEventForLoggers (loggerName) - returnerer antall ILoggingEvent generert av navngitt logger
  • søk (msg) - returnerer a Liste av ILoggingEvent samsvarer med det spesifikke innholdet
  • søk (msg, nivå) - returnerer a Liste av ILoggingEvent samsvarer med spesifisert innhold og alvorlighetsgrad
  • getSize () - returnerer antall ILoggingEvents
  • getLoggedEvents () - gir et umodifiserbart syn på ILoggingEvent elementer

4.2. Enhetstest

La oss deretter lage en JUnit-test for forretningsarbeideren vår.

Vi vil erklære vår MemoryAppender som et felt og programmere det inn i loggsystemet. Deretter starter vi appenderen.

For testene våre setter vi nivået til DEBUG:

@Før offentlige ugyldige oppsett () {Logger logger = (Logger) LoggerFactory.getLogger (LOGGER_NAME); memoryAppender = ny MemoryAppender (); memoryAppender.setContext ((LoggerContext) LoggerFactory.getILoggerFactory ()); logger.setLevel (Nivå.DEBUG); logger.addAppender (memoryAppender); memoryAppender.start (); }

Nå kan vi lage en enkel test der vi instantierer vår BusinessWorker klasse og ring createLogs metode. Vi kan da gjøre påstander om loggene som den genererer:

@Test offentlig ugyldig test () {BusinessWorker-arbeider = 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 testen bruker tre funksjoner i MemoryAppender:

  • Fire logger er generert - en oppføring per alvorlighetsgrad skal være tilstede, med sporingsnivået filtrert
  • Bare en loggoppføring med innholdet beskjed med alvorlighetsgraden på INFO
  • Ingen loggoppføring er tilstede med innhold beskjed og alvorlighetsgrad SPOR

Hvis vi planlegger å bruke samme forekomst av denne klassen i samme testklasse når vi genererer mange logger, vil minnebruk krype opp. Vi kan påberope oss MemoryAppender.clear () metode før hver test for å frigjøre minne og unngå OutOfMemoryException.

I dette eksemplet har vi redusert omfanget av de beholdte loggene til LOGGER_NAME pakke, som vi definerte som “com.baeldung.junit.log“. Vi kan potensielt beholde alle loggene med LoggerFactory.getLogger (Logger.ROOT_LOGGER_NAME), men vi bør unngå dette når det er mulig, da det kan forbruke mye minne.

5. Konklusjon

Med denne veiledningen har vi demonstrert hvordan dekke loggenerering i enhetstestene våre.

Som alltid kan koden bli funnet på GitHub.


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