Spock by Example – Introducing the Series
This article is about the testing framework. For the Star Trek character, see https://en.wikipedia.org/wiki/Spock. For other uses, see https://en.wikipedia.org/wiki/Spock_(disambiguation).
If you are anything like me, you might be thinking something along the lines of: “Yet another testing framework. Why would I want to migrate?” I do not consider myself an early adopter and am usually quite happy to stick to the tools that have proven themselves useful and reliable. Especially, if there is no pain. Or at least I am not aware that there might be any.
A few years ago though, when I was working on a Grails application, I came across Spock and picked it up immediately. The switch was remarkably easy and felt very rewarding to me, especially in hindsight. I might not have felt the pain before, but I definitely did, when – on a new project – I had to switch back. To be fair, at the same time I switched back from Groovy to Java (< 8), which made it probably harder, because writing Java code in general felt somewhat verbose at the time.
So, what do I like about Spock?
What I probably like the most is how concise and expressive the code is, making it both quick to write and easy to read. Spock achieves this by providing a simple yet powerful DSL, which includes built-in mocking, and, of course, the full “Groovy magic”.
A small, but in my opinion noticeable perk is that you can use Strings as method names for your tests. Thus you can use plain English (including punctuation) to describe them, which will then also be shown in your test runner.
When it comes to expectations and matching, Spock allows you to be as precise or unspecific as you like. Using closures you can create the most sophisticated matchers on the fly. Or you can choose just not to care what parameter, or method, or even mock. This results in test code that is more resilient to changes that do not directly affect it. A special case of this is to explicitly expect “nothing”, e.g. no calls on a mock at all. This is a one-liner in Spock (0 * mock._
), completely oblivious of what methods there actually are and hence completely unaffected by any refactorings to the mock’s class.
Verifying order is done by simply putting the expected calls in consecutive blocks of Spock’s DSL rather than creating the mocks differently. Again, you can be as precise or imprecise as you like. In fact, you can even specify by what call on your unit under test the mock call should be triggered. For example, if you call the same method on the unit twice, you can ensure that the mock is called the first time, but not the second.
Spock is conceptually based on tried and tested frameworks like JUnit, jMock, and Mockito, amongst others. This makes it, in my opinion, very easy to learn, if you already have experience with those. Spock does not reinvent the wheel, but it does make it much more comfortable – you might say, they invented the tire. :)
On the “outside” Spock tests, called specifications, look and behave like JUnit tests. Thus you will have the tool support, which comes with that and which most of you are probably used to. You can even run Spock tests in the same suite as your regular JUnit tests, making it very easy not only to migrate using the Boy Scout Rule, but also to experiment. Because it coexists quite peacefully and there is no big setup required, you can easily try Spock on your real application and get a hands-on experience, including all those product-specific real-life scenarios that are never covered by tutorials.
These are just a few things from the top of my head. They are meant to give you a few teasers to kick off what is intended to be a series of posts. Spock has more perks and features, of course. You can check them out on the official website: https://spockframework.org. The purpose of this series, however, is to show you, by example, how it feels to use Spock. In the posts to come there will be examples of using a certain feature and others on how to test a specific problem. I have not made up my mind yet how to pick these examples exactly. Probably I’ll just start right in the middle. After all, that’s where the fun is. What do you think? If you have any requests or proposals, what kind of example you would like to see, feel free to leave a comment anytime.
So much for now, hope to see you again next time. :)