Skip to main content
  1. blog/

🌱 Testing Log Statements in Spring Boot

·2 mins

Overview #

In this article, I’ll explain how to test log statements in Spring Boot using the OutputCaptureExtension.

The code used in the article has been tested with Spring Boot 2.6.2 and JUnit 5.


Dependencies #

We need to have spring-boot-starter-test imported into our project.

This is one of the many “starter packs” for Spring Boot. It includes Junit 5, Spring Test, Spring Boot Test, AssertJ, Hamcrest, Mockito, etc.

Maven (pom.xml) #

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

Gradle (build.gradle) #

testImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-test'

Code #

Let’s create a simple service class called MyService that contains one method that logs an INFO message.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
package com.steelcityamir.app.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    Logger logger = LoggerFactory.getLogger(MyService.class);
   
    public void logMessage(String message) {
        logger.info(message);        
    }
}

Unit Test #

Now let’s create a test that verifies the logging output.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
package com.steelcityamir.app.service;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.system.CapturedOutput;
import org.springframework.boot.test.system.OutputCaptureExtension;

@ExtendWith(OutputCaptureExtension.class)
public class MyServiceTest {
  
    private MyService myservice = new MyService();
    private static final String MESSAGE = "Hello World!";

    @Test
    public void testLogMessage(CapturedOutput output) {
        myservice.logMessage(MESSAGE);
        Assertions.assertTrue(output.getOut().contains(MESSAGE));
    }
}

A few important details to mention here.

  • Line 9 — We tell the test class to use the OutputCaptureExtension.

  • Line 16 — Methods annotated with @Test don’t typically have arguments, but we’ve included an argument for CapturedOutput here to capture the logger output so we can verify it contains what we expect.

  • Line 19 — We call the getOut() method to retrieve the output in our assertion.


Run the Test #

Let’s run our test to see if it passes.

% ./mvnw surefire:test -Dtest=MyServiceTest
[INFO] Scanning for projects...
[INFO] 
[INFO] ------------------------< com.codebyamir:app >------------------------
[INFO] Building one 0.0.1-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-surefire-plugin:2.22.2:test (default-cli) @ one ---
[INFO] 
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.codebyamir.app.service.MyServiceTest
17:28:10.709 [main] INFO com.codebyamir.app.service.MyService - Hello World!
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.175 s - in com.codebyamir.app.service.MyServiceTest
[INFO] 
[INFO] Results:
[INFO] 
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  3.104 s
[INFO] Finished at: 2022-01-08T17:28:11-05:00
[INFO] ------------------------------------------------------------------------