@DataJpaTest in my Pocket

In my last post I’ve written about how to use the new Spring-Boot 1.4 test annotations in combination Spock for more boilerplate free test code. I’ve received some great feedback for this post (and it was even featured on some other blogs like the official Spring blog, Petri Kainulainen’s great Spring and testing blog, as well as Jacob Aae Mikkelsen’s Grails blog), for which I’m very grateful!) and I was also asked if I could provide an example of how to use @DataJpaTest in conjunction with multiple configured datasources. And so I thought great, that’ll be the topic of my next post.

Little Pocket Monster Shop of Horrors

Again I’ve tried to come up with some real world code examples, so let’s assume we have some kind of online shop in which you can buy small monsters in order to let them fight for you. Since cross-platform is all the rage nowadays, it might be a good idea for our shop to offer monsters from different vendors, which might be stored in distinct persistence layers.

We have the following package layout:
packages

The pokemon as well as the digimon package are both configured to use Spring-Data-Jpa with their own datasource. The PokemonConfig looks like this:

And the DigimonConfig looks really similar:

I must admit, this was the first time I’ve used Spring-Boot and Spring-Data-Jpa in conjunction with multiple datasources and the setup wasn’t all smooth sailing for me. The official docs are by no means bad, but the ride get’s pretty bumpy once you’ve got to manually disable different Spring-Boot autoconfigure features (since it is not always 100% percent intuitive on which condition autoconfiguration of a specific feature is disabled automagically – and Oliver Gierke seems to agree on this issue as well 😉) and some aspects mentioned inside the docs – like the usage of EntityManagerFactoryBuilder; I somehow could not inject the builder class without having a @Primary annotated datasource inside my Spring context – didn’t work for me at all. Oliver Gierke’s Spring-Data-Jpa example project on GitHub was a great help for me, since I could nearly copy-paste the EntityManager configuration code. Since I’m still kind of a Spring noob (I’ve started to use Spring in production with the advent of Spring-Boot, beforehand I was a zealous Grails crusader) it’s always a tad bit scary to leave the green meadows of Spring-Boot autoconfiguration and venture forth into the dark depths of vanilla Spring. But nevertheless, it’s almost consistently an enlightening and worthwhile experience once you’ve entangled the ominous stacktrace jungle.

@DataJpaTest

After getting the general application setup, the @DataJpaTest were so darn straight forward and simple, it even feels a bit awkward to devote a blog post to this topic.

You simply have to annotate your tests with @DataJpaTest (and @ContextConfiguration, since Spock is still lacking full support for new Spring-Boot 1.4 test annotations) and you’re good to go. Ah, it feels good to have the cozy Spring-Boot autoconfiguration magic back.

Here is an example test class:

I’m not entirely sure why this does work without further configuration, but while digging into the Spring-Boot source code I’ve found the following comment:

By default, tests annotated with @DataJpaTest will use an embedded in-memory database (replacing any explicit or usually auto-configured DataSource). The @AutoConfigureTestDatabase annotation can be used to override these settings.

So I think it might be safe to assume, these tests don’t need to care whether you are using multiple datasources, or a single autoconfigured one, they seem to be quite decoupled from this part of the application configuration and I think we will get further information about this annotation once Spring-Boot 1.4 is finally released.

I’ve uploaded the sample project on GitHub and I’m looking forward to any comments and/or questions about this topic.

Using Spring-Boot 1.4 testing features with Spock

There was a great blog post over at the spring.io blog a couple of days ago, introducing the new testing improvements coming with Spring-Boot 1.4. I was very intrigued by these new upcoming features, but at the same time kind of sad, that Spock wasn’t mentioned anywhere in the examples (at least you can find some general mentioning about using Spock for testing Spring-Boot applications in the official documentation). In my humble opinion, using Spock to test your Spring-Boot application is a match made in heaven and since I’m a Spring-Boot as well as Spock fan, I thought I just might provide the examples of using Spock alongside the new Spring-Boot 1.4 testing features the original blog post was lacking.

I’ll try to structure this post similar to the original post so you can skip back and forth between the two and checkout the differences in the examples. In order to integrate Spock with Spring (and Spring-Boot) you’ll need this dependency:
'org.spockframework:spock-spring:1.0-groovy-2.4'

The build.gradle config looks like this (there are some additional dependencies for the example project):

Testing without Spring

The original post gave some great advice about unit testing your distinct Spring components: Don’t involve Spring into this! Thanks to the magic of TDD and dependency injection this shouldn’t be a big problem for the main business components of your application (assuming you’ve followed the practices of The Clean Architecture and Hexagonal Architecture). Let’s look at this example of a Spring @Service using some other @Component (there is no implementation difference between @Service and @Component, we’re talking solely semantics here).

I think it’s a shame that many source code examples and tutorials found in the world wide web use artificial and shallow use cases that are as far away from real world usage scenarios as JavaScript is from having a mature build system and so I’ve tried to come up with a useful example application. A friend once told me the process of cooking a sauce hollandaise is a quite difficult one, because you have to monitor the cooking temperature in a very precise fashion. And so this application represents a temperature monitoring system for sauce hollandaise consisting of a HollandaiseTemperatureMonitor service using some Thermometer component.

Test driving the class HollandaiseTemperatureMonitor I’ve come up with the following Spock tests (Since I’m an inhabitant of the part of the world which uses the metric system, all temperature units are in degree Celsius 😉):

This is an example of a pure unit test without involving any Spring dependencies whatsoever. There is still one interesting Spock feature to be found here. We create a Stub Thermometer by simply calling Stub(Thermometer) and instruct this stub to return the givenTemperature afterwards with this line:

thermometer.currentTemperature() >> givenTemperature

If you are somehow unfamiliar with the term Stub here is a great article by Martin Fowler going deep into the differences between Stubs, Mocks, Fakes and so on.

The corresponding production code of HollandaiseTemperatureMonitor that will make this tests pass looks like this:

Integration tests

So far we haven’t seen any of the new Spring-Boot 1.4 testing features, so let’s get to the cool stuff now. When building a Spring-Application I always like to have a really simple smoke test in place, to simply verify that the application starts without errors. This test may look like the following:

Here you can see the new @SpringBootTest annotation at work, which promises to remove all the integration test boiler plate annotations which you needed prior to Spring-Boot 1.4, alas it is not compatible with Spock right now (see this issue). I’ve already submitted a pull request to add Spring-Boot 1.4 compatibility to Spock, but for now we have to use a workaround by explicitly using the @ContextConfiguration annotation:

If Spock finds the @ContextConfiguration on a class, it will assume this is a Spring test and will act accordingly and so this test will pass as expected.

Now let’s move on to the next new testing feature, testing application slices.

Testing Application Slices

Introducing a new use case to our system, we might like to persist some statistic data of our hollandaise cooking process. And what could be a better place to store this data then a relational database? (The answer is nearly everything else, but I wanted some JPA component for the next example and so I had to come up with something…)

Spring-Boot 1.4 introduces some handy shortcuts for integration testing the persistence layer of your application, like the @DataJpaTest annotation. This annotation will instruct Spring to only initialize the components which are needed for the interaction with the persistence (specifically JPA) layer and so we might gain a faster startup time for our integrations tests.

I’ve written a really simply test to demonstrate this feature:

Please note that again I’ve had to add the @ContextConfiguration annotation or else Spock wouldn’t identify the test as a Spring integration test. This is not mentioned in the official documentation and this behavior stems from the same issue as before.

Summary

Okay, that’s it for now. I simply wanted to give some Spock examples for the new Spring-Boot 1.4 testing stuff the original blog post was lacking and I’m quite amused that I’ve discovered some missing Spock support along the way. I hope the proposed workarounds might help someone wondering why this features aren’t working as described inside the documentation. Maybe I’ll try to implement a more stable Spring discovery for the Spock-Spring module in the near future (for now I’m still waiting for my pull request to be merged 😉).

PS:
You can find the source code at GitHub. I’ve also changed to display the source code with the help of the oEmbed Gist Plugin since syntax highlighting and support of markdown code fencing in WordPress was living hell and I couldn’t stand the broken encodings anymore…
I’m still not totally happy with the small column width of the code examples, I think I need to tweak the WordPress theme in order to work better with source code examples.