Posts Tagged ‘idea’

Tune up your JUnit test class template for Idea with the BDD-like syntax, Java 8 and the Mockito-AssertJ duo.

Topics covered in this article may seem trivial. However, from my trainer experience I know that (unfortunately) it is not a common practice. Therefore, I decided to write this short blog post to propagate them and to be able to refer to it in the future.

given-when-then-template

My favorite testing framework for Java (and Groovy) is Spock. However, its mocks are not suitable for some purpose and I still use Mockito in various places. In addition, I still conduct a lot of my testing training in a JUnit/Mockito/AssertJ variant for teams which already have a test suite in that stack and would like to improve their skills without changing the known technology. Therefore, as an interlude, this blog post about testing in the pure Java style and propose how to tune up your JUnit testing framework assuming that you are already using Mockito and AssertJ (you should give them a try in the other case).

This blog post consists of tree parts. Firstly, I propose a BDD-style section-based test structure to keep your test more consist and more readable. Next, I explain how simplify – using the AssertJ and Mockito – constructions with Java 8. Last, but not least, I show how to configure it in IntelliJ IDEA as a default JUnit test (class) template (which isn’t as trivial as it should).

Part 1. BDD-style sections

Well written unit tests should meet several requirements (but it is a topic for a separate post). One of the useful practices is a clear separation into 3 code blocks with precisely defined responsibility. You can read more on that topic in my previous blog post.

As a repetition just the core rules presented in a short form:

  • given – an object under test initialization + stubs/mocks creation, stubbing and injection
  • when – an operation to test in a given test
  • then – received result assertion + mocks verification (if needed)
@Test
public void shouldXXX() {
  //given
  ...
  //when
  ...
  //then
  ...
}

That separation helps to keep tests short and focused on just one responsibility to test (in the end it’s just an unit test).

In Spock those sections are mandatory (*) – without them a test will not even compile. In JUnit there are just comments. However, having them in place encourage people to use them instead of having one big block of mess inside (especially useful for newbies in a testing area).

Btw, the mentioned given-when-then convention is based on (is a subset of) a much wider Behavior-Driven Development concept. You may encounter a similar division on 3 code blocks named arrange-act-assert which in general is an equivalent.

Part 2. Java 8 for AssertJ and Mockito

One of the features of Java 8 is an ability to put default methods in an interface. That can be used to simplify of calling static methods which is prevalent in the testing frameworks such as AssertJ and Mockito. The idea is simple. A test class willing to use a given framework can implement a dedicated interface to “see” those methods as its own methods on code completion in an IDE (instead of static methods from external class which require giving a class name before or a static import). Under the hood those default methods just delegate execution to static methods. You can read more about it in my other blog post.

AssertJ natively supports those construction starting with version 3.0.0. Mockito 1.10 and 2.x are Java 6 compatible and therefore it is required to use a 3rd-party project – mockito-java8 (which should be integrated into Mockito 3 – once available).

To benefit from easier method completion in Idea it is enough to implement two interfaces:

import info.solidsoft.mockito.java8.api.WithBDDMockito;
import org.assertj.core.api.WithAssertions;

class SampleTest implements WithAssertions, WithBDDMockito {

}

Part 3. Default template in Idea

I’m a big enthusiast of omnipresent automation. Wouldn’t it be good to have both given-when-then sections and extra interfaces automatically in place in your test classes? Let’s eliminate those boring things from our life.

Test method

Changing a JUnit test method is easy. One of the possible ways is “CTRL-SHIFT-A -> File Template -> Code” and a modification of JUnit4 Test Method to:

@org.junit.Test
public void should${NAME}() {
  //given
  ${BODY}
  //when
  //then
}

To add a new test in an existing test class just press ALT-INSERT and select (or type) JUnit4 Test Method.

Test class

With the whole test class the situation is a little bit more complicated. Idea provides a way to edit existing templates, however, it is used only if a test is generated with CTRL-SHIFT-T from a production class. It’s not very handy with TDD where a test should be created first. It would be good to have a new position “New JUnit test class” next to “Java class” displayed if ALT-INSERT is pressed being in a package view in a test context. Unfortunately, to do that a new plugin would need to be written (a sample implementation for Spock). As a workaround we can define a regular file template which (as a limitation) will be accessible everywhere (e.g. even in a resource directory).

Do “CTRL-SHIFT-A -> File Template -> Files”, press INSERT, name template “JUnit with AssertJ and Mockito Test”, set extension to “java” and paste the following template:

package ${PACKAGE_NAME};

import info.solidsoft.mockito.java8.api.WithBDDMockito;
import org.assertj.core.api.WithAssertions;

#parse("File Header.java") 
public class ${NAME} implements WithAssertions, WithBDDMockito {

}

Showcase

We are already set. Let’s check how it can look in practice (click to enlarge the animation).

idea-test-templates-in-action

Summary

I hope I convinced you to tune your test template to improve readability of your tests and to safe several keystrokes per test. In that case, please spend 4 minutes right now to configure it in your Idea. Depending on a number of tests written it may start to pay off sooner than you expect :).

Btw, at the beginning of October I will be giving a presentation about new features in Mockito 2 at JDD in Kraków.

JDD logo

Self promotion. Would you like to improve your and your team testing skills and knowledge of Spock/JUnit/Mockito/AssertJ quickly and efficiently? I conduct a condensed (unit) testing training which you may find useful.

Advertisements

Spock is a testing framework for Java and Groovy applications. It allows to write tests in highly expressive specification language which under the hood leverages Groovy compile-time metaprogramming capabilities (especially AST transformations).

Spock developers prefer flat test code formatting with empty lines:

class OrderedInteractionsSpec extends Specification {
  def "collaborators must be invoked in order"() {
    def coll1 = Mock(Collaborator)
    def coll2 = Mock(Collaborator)

    when:
    // try to reverse the order of these invocations and see what happens
    coll1.collaborate()
    coll2.collaborate()

    then:
    1 * coll1.collaborate()

    then:
    1 * coll2.collaborate()
  }
}

I, in turn, prefer more vertically compact formatting without empty lines, but with intend statements after label:

class OrderedInteractionsSpec extends Specification {
    def "collaborators must be invoked in order"() {
        given:
            def coll1 = Mock(Collaborator)
            def coll2 = Mock(Collaborator)
        when:
            // try to reverse the order of these invocations and see what happens
            coll1.collaborate()
            coll2.collaborate()
        then:
            1 * coll1.collaborate()
        then:
            1 * coll2.collaborate()
    }
}

Unfortunately my formatting style was not supported in IntelliJ Idea, even with idea-spock-enhancements plugin. This forced people like me to format it manually and pay attention to automatic code reformat.

Idea 13 provides a lot of new features and improvements. One of them is:

Label Formatting
Code style settings now let you specify custom indentation for the label blocks.

I have to admit I treated it as something not very important and until some time later when a colleague asked me if I know that feature I realized this is something I wanted.

With a simple configuration change Idea 13+ can be configured to support compact Spock specification formatting with code indentation. In File -> Settings (ALT-CTRL-S) -> Code Style -> Groovy set Label indent to 4 (or 2 if preferred) and Label indent style to Indent statements after label.

Spock test code formatting in Idea13

That is all. ALT-CTRL-L (Reformat code) becomes your friend again.

Btw, one more thing pointed out by @mariusz_s. By default labels in Idea looks like ordinal text. In Spock tests labels are part of the specification language and it would be nice to stand them out. It is possible with Spock Enhancements plugin for Idea which make the labels bold and colored.

Label highlighting with Spock plugin

The plugin provides also live inspections for block ordering errors which is very handy and I suggest it to all writing tests in Spock. Code long and prosper ;)