Fighting Testing Boilerplate with IntelliJ IDEA Live Templates

This article will focus on JUnit 5, but most of the things should be applicable for any other testing framework, your imagination is the only limit.

JUnit5 File and code templates

IntelliJ IDEA allows creating test classes with the following shortcut (Ctrl + Shift + T / ⇧ + ⌘ + T). This window allows specifying the test framework, name, package and also can generate test functions.

The IntelliJ IDEA create test modal

The templates which are used for the test classes are defined in the File and Code templates inside the IDE settings.

JUnit5 Test class

This file by itself is sufficient, but it is a good place to add imports which are present in all test classes like assertions, mocks etc.

import static org.junit.jupiter.api.Assertions.*;import org.junit.jupiter.api.Test#parse("File Header.java")class ${NAME} {  ${BODY}}
The JUnit5 Test Class file template

Remember to enable the Live Template otherwise it won’t work.

JUnit5 setUp method

Most of the time the setUp method assigns the class under test to a property which is then used by all test functions. I like to use the following template which streamlined the property assignment with the help of IntelliJ IDEA suggestions.

@org.junit.jupiter.api.BeforeEachvoid setUp() {  systemUnderTest = ${CLASS_NAME}()}
The JUnit5 SetUp Method code template

Live templates

Live templates are a little different from File and Code templates because they can be used when writing code. Templates are applicable only in a defined context, this context prevents namespace pollution. For example: adding a Kotlin function inside a Groovy Gradle file would make no sense.

All the templates, abbreviations and descriptions can be modified to suite a different need.

Adding Gradle dependencies

All tests need some libraries to make testing easier however adding them to the build.gradle mostly consists of copying and pasting them. To help with this, a live template can be used for adding dependencies which are always used together. Please take note of the Applicable context in the bottom left of the modal.

Abbreviation: depsTest
Description: Testing dependencies

The Gradle test dependencies live template for a Groovy Gradle file
The Gradle test dependencies live template for a Kotlin Gradle file

Creating a test function

My most used and simplest live template.

Abbreviation: test
Description: A JUnit5 test

@org.junit.jupiter.api.Testfun `$NAME$`() {    $END$}
The create test function live templates

The variables used are pretty self-explanatory, however instead of $BODY$ I used the $END$ variable. For me using the $END$ is better because it correctly places the cursor after completing the live template. When I used the $BODY$ variable, most of the time I couldn’t think of a test body straight away, so I pressed enter on an empty $BODY$ and then manually navigated the cursor.

All the following live templates also use the Kotlin: class context.

Creating a nested test class

Sometimes test functions can be grouped into a cohesive nested test class. This template can be nicely chained with the test function template.

Abbreviation: nested
Description: A Nested Junit5 class

@org.junit.jupiter.api.Nestedinner class $NAME$ {        $END$}

Create a parameterized enum test

Parameterized help with reducing the number of tests functions when their set-up can be put into variables e.g a converter input. If the variable is an enum class then the following live template can be used.

Abbreviation: paramEnum
Description: A parameterized EnumSource JUnit5 test

@org.junit.jupiter.params.ParameterizedTest@org.junit.jupiter.params.provider.EnumSource($CLASS$::class)fun `$NAME$`($CLASS_NAME$: $CLASS$) {    $END$}
The edit variable modal of a live template

This template uses the edit variable modal in order to specify the test function parameter. The camelCase function inside the expression column works just like the name suggests. Most of the time the parameter name will be the same as the class name, but it is possible to change it during creation.

Create a parameterized test with an arguments provider

For me tests which use parameters from an ArgumentsSource always require the most boilerplate upfront. This live template is much more complicated than the previous ones, but it cuts down the boilerplate significantly.

Abbreviation: paramProvider
Description: A parameterized ArgumentsSource JUnit5 test

@org.junit.jupiter.params.ParameterizedTest@org.junit.jupiter.params.provider.ArgumentsSource($CLASS$::class)fun `$NAME$`($PARAMS$) {    $BODY$}class $CLASS$ : ArgumentsProvider {    override fun provideArguments(context: ExtensionContext?): Stream<out Arguments> {        return Stream.of(            testCase($END$),        )    }        private fun testCase($PARAMS$) =        Arguments.of()}

The testCase function allows the use of named arguments when creating a „test case”.

Summary

Testing involves some boilerplate but luckily modern tools can help with reducing them. These templates are by no means exhaustive, but I hope they give an idea of what can be achieved with them.

If you’re interested in more things that IntelliJ IDEA is capable of feel free to check out my blog post about my most used IDE features.

17 IntelliJ IDEA/Android Studio shortcuts and features for a faster development cycle
A list of IDE shortcuts and features that I use on an almost daily basis

Leave a Comment