hi Konstantinos - I spend a lot of time doing Grails development. Spock is one of the testing frameworks supported by Grails, but I often find it difficult to distinguish which functionality is specifically spock, and what comes out of the box with Grails mixins, etc. Can you explain what spock offers that makes it preferable to other testing frameworks supported by Grails? Also, what are some best practices for using spock with Grails unit tests? thanks, John
You didn't tell me which Grails version you are using. Spock is the default test framework in Grails 2.3+ onwards, so it makes sense to use it as all documentation would refer to it.
Now regarding your confusion, I feel your pain! I had the same problem as well. I was constantly looking at my imports in order to understand which features come from grails.test. * and which from spock.lang.*
The main thing to remember with Grails test is the following:
Grails has this huge advantage of dynamic methods in domain objects (book.findbyNameAndAuthor) which are very handy in development but very difficult to test with plain unit tests. Therefore a lot of Grails testing support
comes from the need to "re-create" this dynamic environment where objects are fetched with dynamic queries. A lot of Grails test annotations are needed for this test environment.
Because Groovy is a very powerful language it already offers several features (that do not appear in Java) already offered by Spock. For example, Spock contains a mocking mechanism on its own, but it very easy to mock
things in Grails/Groovy as well, using mocks, metaclass, expandos etcs.
This means that there are too many ways to combine Spock/Groovy/Grails features on unit tests and thus a lot of documentation you find online has a different view on what a good Grails test is.
My advice (or best practices if you wish) on Grails testing is to talk with your team and decide on ONE way of using all features.
For example, it is perfectly normal to ignore the Spock mocking capabilities and use just normal Groovy and/or Grails mocks. But it is important that all your team member agree on this and all unit tests are written with this way.
I have to admit though, that even if Spock is a revolution for Java/Junit projects it is not as ground-breaking in Groovy/Grails. If you are a seasoned Groovy/Grails developer and have already mastered Grails tests in JUnit, there is no need to rewrite
everything in Spock. You can use Spock just for new tests and keep your old tests.
I have a feeling that Groovy developers are already aware of Spock and will gradually use in their projects. My book is an attempt to convince the Java masses to switch over :-)
Also, apart from JUnit, what other framework have you used in your Grails tests? Did you have something specific in mind?
hi Kostis, thanks very much for your thoughtful answer. Most of the test code I have written over the past 3+ years has been on Grails (2.3, 2.4) projects. As you mentioned, there is an embarrassment of riches when it comes to mocking test collaborators. While I typically use 'mockFor' to mock services on controller tests, I also use metaClass programming in service tests to mock collaborating service methods that are not themselves directly under test. I probably need to take a closer look to determine exactly which testing/mocking libraries our team actually uses, because it's not easy to know at a glance.