Monday, December 8, 2014

Mocking non-injected services with groovy

Sometimes we'll come across a piece of code that we want to test, but we're not able to inject a mock because the service is hard coded into the class. Consider this:

class Client {

    private final Service databaseService = new DatabaseService();

    def find(long id) {
       databaseService.find(id)
    }
}

Testing the find method would be difficult because the database service is not injected.

Groovy mocks and stubs can be used as categories for this case.

class ClientTest {

    @Test
    private testFind() {
        MockFor mock = new MockFor(DatabaseService)
        mock.demand.find { id -> someObject }
        mock.use {
           Client client = new Client()
           client.find(1L) // this will use the mock and return someObject
        }
    }
}

While injecting dependencies is easier, this is an alternative method when injection isn't available. See Using MockFor and StubFor for more details in the groovy docs.