Mocking Groovy's HTTPBuilder
I ran into a head-scratcher today when trying to unit test some Groovy code. The code under test interacts with an HTTP web service using Groovy's great HTTPBuilder, which wraps Apache's HttpClient. Obviously, I wanted to mock the interaction with the HTTP server to limit the scope of my tests.
Groovy makes it easy to create simple mocks using
maps. To mock a class with a
map, one must create a map which is keyed by the methods names to be
tested and storing closures for the mock method implementation. For
example, if we wish to mock out the HTTPBuilder, which has a "post"
method, we can accomplish it using the map defined by mapMock
.
class HTTPBuilder {
def post(...) { /* real implementation */ }
}
def mapMock = ["post": { /* mock implementation */ }]
This map-mock approach was working great for mocking out the post, put,
and delete methods in HTTPBuilder, but the get
method was giving me
quite a bit of trouble. The closure in my get
method mock was never
executed.
After taking a step back, I realized that the map's get
method (the
one used to return the value at a specific key) was getting called
instead of the key within the map called get.
The simple solution was to switch to use an Expando mock instead of a map mock.
def expandoMock = new Expando()
expandoMock.get = { /* mock implementation */ }
I know I'm late to the train, buy Groovy is a breathe of fresh air compared to Java.