Console output unit testing in the Kotlin application

Are you looking for a way to test your console output (println()) in your Kotlin project?

In this post, I’m going to walk you through the process of creating a simple project setup that allows you to unit test the console output of the application.

The project will use Gradle but you can achieve the same effect using Maven, just adjust the dependencies to your needs.

Setting up the Gradle project

Create a new folder and begin the project initialization process there.

mkdir pocket-adder
cd pocket-adder
gradle init

Then, answer the questions accordingly.

Starting a Gradle Daemon (subsequent builds will be faster)

Select type of project to generate:
  1: basic
  2: application
  3: library
  4: Gradle plugin
Enter selection (default: basic) [1..4] 2

Select implementation language:
  1: C++
  2: Groovy
  3: Java
  4: Kotlin
  5: Swift
Enter selection (default: Java) [1..5] 4

Select build script DSL:
  1: Groovy
  2: Kotlin
Enter selection (default: Kotlin) [1..2] 2

Project name (default: pocket-adder):
Source package (default: pocket.adder):

The project has been generated, it’s time to open it in the IDE.

Adding dependencies

By default, the application will have a default test environment already set up, with basic asserters and the JUnit library in place.

It happens thanks to these out-of-the-box dependencies:

    // Use the Kotlin test library.
    testImplementation("org.jetbrains.kotlin:kotlin-test")

    // Use the Kotlin JUnit integration.
    testImplementation("org.jetbrains.kotlin:kotlin-test-junit")

In order to be able to test console output, we will use a helpful library called system-lambda. It allows us to get the System class output streams as the convenient lambda functions.

Don’t worry about the compatibility between this library which uses java.lang.SystemΒ class and Kotlin.
Why? Take a quick look at the Kotlin internals. The println() method is just a wrapper for the good old Java System.out.println():


/** Prints the given [message] and the line separator to the standard output stream. */
@kotlin.internal.InlineOnly
public actual inline fun println(message: Any?) {
    System.out.println(message)
}
kotlin/io/Console.kt

Add the dependency into the build.gradle.kts file:


dependencies {

...

    testImplementation ("com.github.stefanbirkner:system-lambda:1.2.0")
}
build.gradle.kts

Testing the console output

Let’s put this in action. At first, let’s modify the existing test class and let the generated application greet us πŸ‘‹

package pocket.adder

import com.github.stefanbirkner.systemlambda.SystemLambda.*
import org.junit.Assert
import org.junit.Test

class AppTest {

    @Test
    fun `main method should return a proper greeting`() {
        val output = tapSystemOut {
            main(emptyArray())
        }

        Assert.assertEquals(
            "Hello world.",
            output.trim()
        )
    }

}
AppTest.kt

Then run it. No surprises, it’s all green.

For the sake of clarity, let’s change the implementation and test case little bit (because this project is the pocket-adder after all).

package pocket.adder

class App {

    fun addTwo(first: Int, second: Int): Int {
        val sum = first + second
        println("$first + $second = $sum")
        return sum
    }

}

fun main(args: Array<String>) {
    println("Hello World.")
}
App.kt

And the test class:

package pocket.adder

import com.github.stefanbirkner.systemlambda.SystemLambda.*
import org.junit.Assert.assertEquals
import org.junit.Test

class AppTest {

    @Test
    fun `should add two numbers and return the sum`() {
        val firstNumber = 2
        val secondNumber = 38

        val output = tapSystemOut {
            App().addTwo(firstNumber, secondNumber)
        }

        assertEquals(
            "$firstNumber + $secondNumber = 40",
            output.trim()
        )
    }

}
AppTest.kt

The test is passing 🟒 .

Conclusion

As you can see, getting your console output in the unit tests is very simple and straightforward.

This setup will be used for the series of posts about design patterns in Kotlin, if you’re interested read more here.

Resources

Leave a Reply

Your email address will not be published. Required fields are marked *