Однажды я столкнулся с той же проблемой, когда я не совсем привык к the life in the IoC world
. Поле @Autowired
одного из моих bean-компонентов является нулевым во время выполнения.
Основная причина заключается в том, что вместо использования автоматически созданного компонента, поддерживаемого контейнером Spring IoC (чье поле @Autowired
равно indeed
] правильно введенный), я newing
мой собственный экземпляр этого типа бобов и его использование. Конечно, это поле @Autowired
равно нулю, потому что Spring не имеет возможности его ввести.
Я думаю, вы могли бы решить свою проблему с помощью пользовательского приложения. Создайте тестовый appender, который реализует org.apache.log4j.Appender
, и установите ваш appender в log4j.properties
и загрузите его при выполнении тестовых примеров.
Если вы перейдете к тестовому жгуту с этого appender
, вы может проверять зарегистрированные сообщения
Для тестирования slf4j, не полагаясь на конкретную реализацию (например, log4j), вы можете предоставить свою собственную реализацию регистрации slf4j, как описано в этом FAQ SLF4J . Ваша реализация может записывать сообщения, которые были занесены в журнал, а затем опросить ваши модульные тесты для проверки.
Пакет slf4j-test выполняет именно это. Это встроенная в память реализация slf4j, которая предоставляет методы для извлечения зарегистрированных сообщений.
slf4j-test
можно найти здесь: github.com/jaegertracing/jaeger-client-java/pull/378/files . По общему признанию, их документация также замечательна.
– Debosmit Ray
6 April 2018 в 01:59
Создать тестовое правило:
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.read.ListAppender;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.stream.Collectors;
public class LoggerRule implements TestRule {
private final ListAppender<ILoggingEvent> listAppender = new ListAppender<>();
private final Logger logger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
@Override
public Statement apply(Statement base, Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
setup();
base.evaluate();
teardown();
}
};
}
private void setup() {
logger.addAppender(listAppender);
listAppender.start();
}
private void teardown() {
listAppender.stop();
listAppender.list.clear();
logger.detachAppender(listAppender);
}
public List<String> getMessages() {
return listAppender.list.stream().map(e -> e.getMessage()).collect(Collectors.toList());
}
public List<String> getFormattedMessages() {
return listAppender.list.stream().map(e -> e.getFormattedMessage()).collect(Collectors.toList());
}
}
Затем использовать его:
@Rule
public final LoggerRule loggerRule = new LoggerRule();
@Test
public void yourTest() {
// ...
assertThat(loggerRule.getFormattedMessages().size()).isEqualTo(2);
}
Вместо издевательств SLF4J вы могли бы разместить важные вызовы журналов, которые вам нужны , чтобы протестировать их собственные методы, которые вы можете легко высмеивать.
Если вы действительно хотите издеваться над SLF4J , Я бы поспорил, что вы могли бы создать своего собственного провайдера для этого, что позволит вам поставлять фальшивый регистратор со стороны SLF4J вместо того, чтобы вводить его в свои служебные объекты.
Лучшая тестовая реализация SLF4J, которая очень хорошо работает в среде с одновременным выполнением теста, - https://github.com/portingle/slf4jtesting
Я пробовал в ходе небольшого обсуждения тестирования журналов slf4j и ограничений существующих тестовых подходов, когда дело доходит до выполнения одновременного тестирования.
Я решил поместить свои слова в код и что git repo является результатом.
Подобно @Zsolt, вы можете mock log4j Appender
и установить его на Logger
, а затем проверить вызовы на Appender.doAppend()
. Это позволяет вам протестировать без изменения реального кода.