J'utilise slf4j et je souhaite tester mon code pour m'assurer que les messages d'avertissement/journal des erreurs sont générés sous certaines conditions. Je préférerais qu'il s'agisse de tests unitaires stricts. Par conséquent, je préférerais ne pas avoir à extraire la configuration de la journalisation à partir d'un fichier afin de vérifier que les messages du journal sont générés. Le cadre moqueur que j'utilise est Mockito.
Je pense que vous pourriez résoudre votre problème avec un appender personnalisé. Créez un appender test qui implémente le org.Apache.log4j.Appender
, définissez votre appender dans le log4j.properties
et chargez-le lorsque vous exécutez des scénarios de test.
Si vous rappelez le test à partir de cette appender
, vous pouvez vérifier les messages enregistrés
Pour tester slf4j sans s'appuyer sur une implémentation spécifique (telle que log4j), vous pouvez fournir votre propre implémentation de journalisation slf4j comme décrit dans this SLF4J FAQ . Votre implémentation peut enregistrer les messages consignés puis être interrogée par vos tests unitaires pour validation.
Le slf4j-test package fait exactement cela. Il s'agit d'une implémentation de journalisation slf4j en mémoire qui fournit des méthodes pour récupérer les messages journalisés.
Une meilleure implémentation de test de SLF4J qui fonctionne vraiment bien dans un environnement avec exécution de tests simultanés est https://github.com/portingle/slf4jtesting
J'ai abordé quelques discussions sur les tests de journalisation slf4j et les limites des approches de test existantes en matière d'exécution de tests simultanés.
J'ai décidé de mettre mes mots dans le code et que git repo est le résultat.
Au lieu de vous moquer de SLF4J, vous pouvez placer les appels de consignation importants que vous need testez à l’intérieur de leurs propres méthodes que vous pouvez simuler plus facilement.
Si vous voulez vraiment vous moquer de SLF4J, je parierais que vous pourriez créer votre propre fournisseur, ce qui vous permettrait de fournir un faux enregistreur du côté de SLF4J au lieu d’en injecter un dans vos objets de service.
Comme pour @Zsolt, vous pouvez vous moquer de log4j Appender
et le définir sur la Logger
, puis vérifier les appels à Appender.doAppend()
. Cela vous permet de tester sans avoir à modifier le code réel.
Créez une règle de test:
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());
}
}
Alors utilisez-le:
@Rule
public final LoggerRule loggerRule = new LoggerRule();
@Test
public void yourTest() {
// ...
assertThat(loggerRule.getFormattedMessages().size()).isEqualTo(2);
}