Sometimes we are working on a new feature in our code and we want to write a specification for it without yet really implementing the feature. To indicate we know the specification will fail while we are implementing the feature we can add the
@PendingFeature annotation to our specification method. With this annotation Spock will still execute the test, but will set the status to ignored if the test fails. But if the test passes the status is set to failed. So when we have finished the feature we need to remove the annotation and Spock will kindly remind us to do so this way.
Spock supports JUnit rules out of the box. We simply add a rule with the
@Rule annotation to our Spock specification and the rule can be used just like in a JUnit test. The Spring Boot project contains a JUnit rule
OutputCapture to capture the output of
When we mock or stub methods we can use the method arguments passed to the method in the response for the mocked or stubbed method. We must write a closure after the rightShift operator (
>>) and the closure arguments will resemble the arguments of the mocked or stubbed method. Alternatively we can use a single non-typed argument in the closure and this will contains the method argument list.
Spock has some great features to write specifications or tests that are short and compact. One of them is the
old() method. The
old() method can only be used in a
then: block. With this method we get the value a statement had before the
when: block is executed.
Say you have a arbitrary class under test, which is dependent on a class DataProcessor which has a method with the following signature:
String processData(String data, MultivaluedMap <String, String> params, Token token)
you might want to stub it with Mockito 1.9.5 in the following way to match the generic typed class:
when(dataProcessor.processData(anyString(), any(MultivaluedMap.class), any(Token.class))).thenReturn(processedData);
However running this, gives the following error:
Invalid use of argument matchers!
3 matchers expected, 4 recorded:
This exception may occur if matchers are combined with raw values:
someMethod(anyObject(), "raw String");
When using matchers, all arguments have to be provided by matchers.
someMethod(anyObject(), eq("String by matcher"));
This is caused by the generic typed MulitvaluedMap.
MultivaluedMap <String, String> map = Mockito.any();
when(dataHandlerMock.getResult(anyString(), map, any(TokenDataBean.class))).thenReturn(jsonString);
Run the test and it will pass (these lines at least :-)!
Albert van Veen wrote a blog post about Using ArgumentMatchers with Mockito. The idea is to let a mocked or stubbed service return a different value based on the argument passed into the service. This is inspired me to write the same sample with Spock.
Spock already has built-in mock and stub support, so first of all we don’t need an extra library to support mocking and stubbing. We can easily create a mock or stub with the
Stub() methods. We will see usage of both in the following examples.
Say you want to test a method from class which extends some kind of superclass. Sometimes you can be dependent on code in the superclass, which is undesirable in a test.
Now actually, the first thing you should consider is to refactor your code, because it’s violating the Single Responsibility design principle:
there is more than one reason why your class is subject to change. Another advice is to favor composition over inheritence. In this way you can mock the code you are collaborating with.
Having said that, sometimes you run into legacy code you just have to work with and aren’t able to refactor due to circumstances. Here’s a trick I found on Stackoverflow to “mock” a superclass method to do nothing with mockito. Continue reading
Willem Cheizoo already wrote an blog post about How to test for an exception with JUnit and this inspired me to write the same sample with Spock.
In Spock we can use the
thrown() method to check for exceptions. We can use it in a
then: block of our test.
Testing for exceptions in JUnit is something we have to deal with! We want to test if an exception occurs in a particular situation, or even if the exception contains a particular message. The question is: How to test for an exception in Junit? Continue reading
Mockito is a mock framework which you can use to write simple and clean tests. One of it’s nice features is the ArgumentMatcher. With the ArgumentMatcher you can determine the outcome of your mocked service or repository based on any condition you want.
Imagine we have a CandyService which can get a list of candies which are liked by a specific customer. This service uses the external ChocalateService which specifically checks if the customer likes chocolate. Continue reading