Blog post Java, Technical

Introduction to a few Java test frameworks

Overview of interesting topics from Java Conference held in Barcelona in June 2017. Brief look at Spock, AssertJ and Awaitility Java test frameworks.

We had the pleasure of attending the Java conference in Barcelona which was held from the 19th to the 21st of June. There were various topics and presentations at the conference, most of which were about Reactive, Microservices, Functional Programming, and Testing.

Photo from the official Twitter account @jbcnconf

Let's take a look at what is interesting in the world of testing.

Our attention was quickly taken by the Spock framework. Although it has existed since 2008, it somehow went below our radar.

Spock is built on Groovy and it seems to support easily writable and readable tests, which is very useful if you practice Behavior Driven Development (BDD).

Test methods can take an unconventional approach and can be declared between apostrophes, which mean you can use a sentence as a method name.

For example:

def "users younger than 18 should be accompanied by parent"(){
  given:
    User user = new User()
    def service = Service()
  when:
    user.age(11)
  then:
    service.shouldBringParent(user) == true
}

I do like assertion failure reports, which presents all values caught during evaluation in a nice format. Something like this:

Condition not satisfied:
stack.size() == 2
|     |      |
|     1      false
[push me]

If you want to test multiple options/conditions, again you can format input in a readable way:

def "maximum of two numbers"(int a, int b, int c) {
  expect:
  Math.max(a, b) == c

  where:
  a | b | c
  1 | 3 | 3
  7 | 4 | 7
  0 | 0 | 0
}

Here, the test will run with 3 sets of data.

Spock has built in a mocking and stubbing mechanism with Mock and Stub. Stub is useful when you want to force certain return values, or even some side effects.

The second framework I liked was AssertJ. This framework has nice assertions for Collections, for example like this:

assertThat(composers).extracting("name")
			         .hasSize(2)
                     .contains("Mozart", "Bach")

or using a Java 8 method reference

assertThat(composers).extracting(Composer::getName)
                     .doesNotContain("Mann", "Camus");

You can chain your assertions, like in the first example. AssertJ has the possibility for “soft assertions”, which means that a test will not break as soon as the first assertion is not met. Instead, all following assertions will be done, and you will get a list of all of those that failed. There are built in assertions for Date, File and Stream.

Also, you can simply compare complex objects using isEqualToComparingFieldByField or isEqualToIgnoringNullFields.

Both frameworks can use the IDE’s auto-complete mechanism to help us find the correct assertion. Also, both frameworks give a more natural "reading", which helps to understand the purpose of test.

The third item we would like to introduce is the DSL library called Awaitility. This one is handy for testing asynchronous calls. For example:

await().atLeast(1, SECONDS).and().atMost(2, SECONDS).until(value(), equalTo(1));

It has built in deadlock detection and polling intervals can be various, not just fixed steps, like Fibonacci, or even a custom interval.

There is the possibility to use conditionEvaluationListener, which may be used to observe intermediate values.

It seems that all these frameworks have very useful gadgets to give, and introducing them would help us in our everyday work. We will try to introduce them into our projects, and improve our testing even further.

Contact us to discuss your project.
We're ready to work with you.
Let's talk