Утвърждаване на регистрационни съобщения с JUnit

1. Въведение

В този урок ще разгледаме как можем да покрием генерираните регистрационни файлове при тестване на JUnit .

Ще използваме slf4j-api и реализацията на logback и ще създадем персонализиран добавяне, който можем да използваме за твърдение на регистрационен файл .

2. Зависимости на Maven

Преди да започнем, нека добавим зависимостта от регистрацията . Тъй като той реално реализира slf4j-api , той автоматично се изтегля и инжектира в проекта от Maven transibility:

 ch.qos.logback logback-classic. 1.2.3 

AssertJ предлага много полезни функции при тестване, така че нека добавим и зависимостта му към проекта:

 org.assertj assertj-core 3.15.0 test 

3. Основна бизнес функция

Сега, нека създадем обект, който ще генерира дневници, на които можем да основаваме тестовете си.

Нашият обект BusinessWorker ще изложи само един метод. Този метод ще генерира дневник със същото съдържание за всяко ниво на дневника. Въпреки че този метод не е толкова полезен в реалния свят, той ще послужи добре за целите ни на тестване:

public class BusinessWorker { private static Logger LOGGER = LoggerFactory.getLogger(BusinessWorker.class); public void generateLogs(String msg) { LOGGER.trace(msg); LOGGER.debug(msg); LOGGER.info(msg); LOGGER.warn(msg); LOGGER.error(msg); } }

4. Тестване на регистрационните файлове

Искаме да генерираме дневници, така че нека създадем файл logback.xml в папката src / test / resources . Нека го направим възможно най-опростен и да пренасочим всички регистрационни файлове към добавка CONSOLE :

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

4.1. MemoryAppender

Сега нека създадем персонализиран приложение, което съхранява регистрационните файлове в паметта . Ще разширим ListAppender, който предлага регистрацията , и ще го обогатим с няколко полезни метода:

public class MemoryAppender extends ListAppender { public void reset() { this.list.clear(); } public boolean contains(String string, Level level) { return this.list.stream() .anyMatch(event -> event.getMessage().toString().contains(string) && event.getLevel().equals(level)); } public int countEventsForLogger(String loggerName) { return (int) this.list.stream() .filter(event -> event.getLoggerName().contains(loggerName)) .count(); } public List search(String string) { return this.list.stream() .filter(event -> event.getMessage().toString().contains(string)) .collect(Collectors.toList()); } public List search(String string, Level level) { return this.list.stream() .filter(event -> event.getMessage().toString().contains(string) && event.getLevel().equals(level)) .collect(Collectors.toList()); } public int getSize() { return this.list.size(); } public List getLoggedEvents() { return Collections.unmodifiableList(this.list); } }

Класът MemoryAppender обработва Списък, който автоматично се попълва от системата за регистриране.

Той излага разнообразни методи, за да обхване широк спектър от цели на теста:

  • reset () - изчиства списъка
  • съдържа (msg, level) - връща true само ако списъкът съдържа ILoggingEvent, съответстващ на определеното съдържание и ниво на сериозност
  • countEventForLoggers (loggerName) - връща броя на ILoggingEvent, генериран от поименен регистратор
  • search (msg) - връща списък на ILoggingEvent, съответстващ на конкретното съдържание
  • search (msg, level) - връща Списък на ILoggingEvent, съответстващ на определеното съдържание и ниво на сериозност
  • getSize () - връща броя на ILoggingEvent s
  • getLoggedEvents () - връща немодифицируем изглед на елементите ILoggingEvent

4.2. Единичен тест

След това нека създадем JUnit тест за нашия бизнес работник.

Ще декларираме нашия MemoryAppender като поле и ще го инжектираме програмно в лог системата. След това ще започнем приложението.

За нашите тестове ще зададем нивото на DEBUG :

@Before public void setup() { Logger logger = (Logger) LoggerFactory.getLogger(LOGGER_NAME); memoryAppender = new MemoryAppender(); memoryAppender.setContext((LoggerContext) LoggerFactory.getILoggerFactory()); logger.setLevel(Level.DEBUG); logger.addAppender(memoryAppender); memoryAppender.start(); }

Сега ние можем да създадем един прост тест, при който ние примери ни BusinessWorker клас и се обадете на generateLogs метод. След това можем да правим твърдения в дневниците, които той генерира:

@Test public void test() { BusinessWorker worker = new BusinessWorker(); worker.generateLogs(MSG); assertThat(memoryAppender.countEventsForLogger(LOGGER_NAME)).isEqualTo(4); assertThat(memoryAppender.search(MSG, Level.INFO).size()).isEqualTo(1); assertThat(memoryAppender.contains(MSG, Level.TRACE)).isFalse(); }

Този тест използва три функции на MemoryAppender :

  • Генерирани са четири регистрационни файла - трябва да присъства по един запис на сериозност, като нивото на проследяване е филтрирано
  • Само един запис в дневника със съдържанието на съобщението със степента на сериозност на INFO
  • Няма запис в дневника със съобщение за съдържание и сериозност TRACE

Ако планираме да използваме същия екземпляр на този клас в същия тестов клас, когато генерираме много регистрационни файлове, използването на паметта ще пропълзи. Можем да извикаме метода MemoryAppender.clear () преди всеки тест, за да освободим паметта и да избегнем OutOfMemoryException .

В този пример намалихме обхвата на запазените регистрационни файлове до пакета LOGGER_NAME , който определихме като „ com.baeldung.junit.log “. Потенциално бихме могли да запазим всички регистрационни файлове с LoggerFactory.getLogger (Logger.ROOT_LOGGER_NAME), но трябва да избягваме това, когато е възможно, тъй като може да консумира много памет .

5. Заключение

С този урок демонстрирахме как да обхванем генерирането на регистрационни файлове в нашите модулни тестове .

Както винаги, кодът може да бъде намерен в GitHub.