Home » Java » Enterprise Java » Grails 3.3 Integration Testing with Spock Mocks

About Ted Vinke

Ted Vinke
Ted is a Java software engineer with a passion for Web development and JVM languages and works for First8, a Java Web development company in the Netherlands.

Grails 3.3 Integration Testing with Spock Mocks

It is easy to use the Spock Framework, shipped with Grails, to mock or stub a collaborator (such as a service) in our Grails unit tests.

The Testing chapter explains a bit about mocking collaborators, doWithSpring/doWithConfig callback methods, the FreshRuntime annotation to mock beans in tests — but they’re mainly for unit testing.

How about mocking beans in an integration test?

Example

What if we have a controller

class AnimalRegistrationController {
    AnimalRegistrationService animalRegistrationService

    def arrival(ArrivalCommand arrival) {

        animalRegistrationService
            .registerArrival(arrival)
            .map { ArrivalErrorMessage aem ->
                renderErrors(aem)
            }.orElse {
                render status: 200
            }
    }
}

which calls a service, which calls a repository – which might do external calls which you don’t want to happen in an integration test.

class AnimalRegistrationService {
    ArrivalRepository arrivalRepository

    Optional registerArrival(Arrival arrival) {
        arrivalRepository.registerArrival(arrival)
    }

}

Previously I wrote that Grails 3.3 has Spock 1.1 — which gave us a few new features to use such as a default answer for java.util.Optional…but it gave us more!

1. DetachedMockFactory and TestConfiguration

Now we also have a DetachedMockFactory we can use to declare mocks outside the hierarchy of a outside of a Specification, e.g. in a Spring configuration.

I got triggered by this article about Spring Integration testing, and I adjusted it to work for Grails 3.3 — which is based on Spring Boot but doesn’t quite use all the Spring annotations we’re used to in a vanilla Spring application.

So we create a configuration, specifically for testing, in src/test/groovy using a DetachedMockFactory like

import spock.mock.DetachedMockFactory
import org.springframework.boot.test.context.TestConfiguration
import org.springframework.context.annotation.Bean
...

@TestConfiguration
class TestRepositoryConfig {

    private DetachedMockFactory factory = new DetachedMockFactory()

    @Bean
    ArrivalRepository arrivalRepository() {
        factory.Mock(ArrivalRepository)
    }
}

2. Integration test

We can now use the mocked bean in our Grails 3 integration test, by injecting it by type using @Autowired. We can create the expectations as usual.

@Integration
class ArrivalApiIntegrationSpec extends Specification {

    @Value('${local.server.port}')
    Integer serverPort

    @Autowired
    ArrivalRepository mockedArrivalRepository

    void "should create an arrival"() {

        given:
        1 * mockedArrivalRepository.registerArrival(_) >> {
            Optional.empty()
        }

        when:
        def response = new RestBuilder().post('http://localhost:{serverPort}/api/arrivals') {
            urlVariables([serverPort: serverPort])
            json {
                animalId = 1
                date = '2017-01-01'
            }
        } 

        then:
        response.status == 200
    }
}

3. Dependency

For the above to work, you actually have to pull in one essential spock-lang dependency.

Add it to your build.gradle

dependencies {
  ...
  testCompile 'org.spockframework:spock-core:1.1-groovy-2.4'
  testCompile 'org.spockframework:spock-spring:1.1-groovy-2.4'

Bada-bing. It’s done.

That’s it

We have now full control over our mocked beans, as if we were in a unit test.

(0 rating, 0 votes)
You need to be a registered member to rate this.
Start the discussion Views Tweet it!
Do you want to know how to develop your skillset to become a Java Rockstar?
Subscribe to our newsletter to start Rocking right now!
To get you started we give you our best selling eBooks for FREE!
1. JPA Mini Book
2. JVM Troubleshooting Guide
3. JUnit Tutorial for Unit Testing
4. Java Annotations Tutorial
5. Java Interview Questions
6. Spring Interview Questions
7. Android UI Design
and many more ....
I agree to the Terms and Privacy Policy
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments