This article covers a Bloomreach Experience Manager version 11. There's an updated version available that covers our most recent release.

Suppress log messages during unit tests

During unit tests, it can happen that you want to suppress certain log messages to some appender. For example

  1. Your unit test can be about asserting that some exception takes place, which results in some log warning or error. Typically, during these kind of unit tests, you might want to temporarily suppress some logging to the console, as the warnings/errors are expected and intentional.
  2. Your unit tests might bootstrap a repository by extending org.onehippo.repository.testutils.RepositoryTestCase that bootstraps content of your project. However, your bootstrap content might include content that is not needed for the unit tests, and contains namespaces that are not bootstrapped by RepositoryTestCase (for example hippo:frontend namespace)

There are two ways to suppress log messages, both having their own use cases (typically either use case 1 or 2 above). You need to have a compile dependency on hippo-repository-testutils. The ExecuteOnLogLevel is available since 2.24.00 and StringMatchFilter since 2.24.02

  1. Suppress log messages with org.onehippo.repository.testutils.ExecuteOnLogLevel
  2. Suppress log messages with org.onehippo.repository.testutils.log4j.StringMatchFilter

Suppress log messages with ExecuteOnLogLevel

When some unit test its purpose is for example to verify that some broken configuration does not break the application, or when some action results in some error that is logged but does not break the application, you can suppress the warning / error log during unit tests by wrapping some invocation that you know will result in the warn or error with ExecuteOnLogLevel.

Assume you want to assert that failing Spring configuration in addon modules does not break the HST SpringComponentManager. Your tests could be as follows:

@Test
public void testFailedModuleInstances() throws Exception {
  final SpringComponentManager componentManager = ....
  .........
  // assume componentManager.start() logs a warning about the wrong module
  componentManager.start();
  assertTrue(....)
  componentManager.stop();
  componentManager.close();
 } 

Now, above, the componentManager.start() logs a warning in case there a incorrect modules. The test is about the fact that incorrect modules should not fail the entire SpringComponentManager to start. Hence, the warning log is intentional and expected, thus, can be considered to be noise in the console output. Hence, suppressing the warning is cleaner. You can do this by wrapping the method (say method doI) that logs the warning with:

 ExecuteOnLogLevel.xxx(new Runnable() {
    @Override
    public void run() {
        doIt()
    }
  }, loggerName1, loggerName2, loggerName3 .... loggerNameN); 

where above the xxx can be

  1. debug
  2. info
  3. warn
  4. error
  5. fatal

and where loggerName1, loggerName2 ... loggerNameN is a varargs of all the loggers that should be during the doIt() invocation be temporarily set to log level xxx. The above componentManager unit test with the start() method that logs warnings can thus be rewritten as below to make sure that componentManager.start() won't log any warnings to the console : Namely, during the start() invocation, temporarily the log level is set to ERROR.

@Test
public void testFailedModuleInstances() throws Exception {
  final SpringComponentManager componentManager = ....
  .........
  ExecuteOnLogLevel.error(new Runnable() {
    @Override
    public void run() {
        componentManager.start();
    }
  }, SpringComponentManager.class.getName());

  assertTrue(....)
  componentManager.stop();
  componentManager.close();
}

Suppress log messages with StringMatchFilter

When some unit test bootstraps a repository that results in some warnings about content bootstrapping that is not used for the unit test, it is cleaner to suppress these warnings to keep the console output during unit tests clean. In case you mock some objects, but do not mock them completely which causes some, for the unit tests, harmless warnings, it is cleaner to suppress these warnings. The StringMatchFilter is a simple org.apache.log4j.spi.Filter that can be added to a log4j appender to suppress some configurable log messages through log4j-filters.txt based on a contains criteria.

Step 1

Change the log4j.xml configuration the console appender to include the StringMatchFilter filter:

<appender name="console" class="org.apache.log4j.ConsoleAppender">
  <param name="threshold" value="ERROR"/>
  <layout class="org.apache.log4j.PatternLayout">
     <param name="ConversionPattern"
            value="%d{dd.MM.yyyy HH:mm:ss} %-5p [%C.%M():%L] %m%n"/>
  </layout>
  <filter class="org.onehippo.repository.testutils.log4j.StringMatchFilter"/>
</appender>

Step 2

In the same location as the log4j.xml file add a log4j-filters.txt that contains all the filters. Every line that does not start with a # is a filter. Any log message that contains the text of one of the filter lines is suppressed. For example, if the log4j-filters.txt is as follows:

#
# Copyright (C) 2011 Hippo B.V.
#

Error initializing content for frontend-templatecomposer.xml in '/hippo:configuration/hippo:frontend/cms'
Error initializing content for frontend-loader.xml in '/hippo:configuration/hippo:frontend/cms/cms-static'
Error initializing content for frontend-cluster.xml in '/hippo:configuration/hippo:frontend/cms'

Then this filter means that any log message that contains in its message one of the three lines above (not the ones that start with #) is suppressed and not logged to the console appender. Thus, for example the message [Error initializing content for frontend-templatecomposer.xml in '/hippo:configuration/hippo:frontend/cms' because of unknown namespace 'hippo:frontend'] will be suppressed.

Did you find this page helpful?
How could this documentation serve you better?
On this page
    Did you find this page helpful?
    How could this documentation serve you better?