I’m trying to test controller’s action in integration test. It’s a simple scenario where action that I’m trying to test is calling service’s method. I’m trying to override that method using metaclass but it looks like it’s not working, i.e. real method of the service always getting called instead of the one that I override using metaclass. What am I doing wrong here?
Here is the controller’s method:
class MyController {
MyService myService
def methodA() {
def u = myService.find(params.paramA)
render view: "profile", model: [viewed: u]
}
Here is how I implement integration test:
class MyControllerTests extends GroovyTestCase {
MyController controller
void testMethodA() {
controller = new MyController()
// Mock the service
MyService mockService = new MyService()
mockService.getMetaClass().find = { String s ->
[]
}
controller = new MyController()
controller.myService = myService
controller.methodA()
}
P.S. I’m using grails 2.0.0 in STS 2.9.2
First off all I recommend to use Spock Framework which is really nice piece of testing library, besides integrates with Grails pretty well.
Your test would then look like:
If you prefer to stay without using Spock, for mock you need the simplest way will be using Groovy coercion. Check this out:
This is map coercion. In your case when mocking single method not even Map is necessary, so you can write it simpler.
This is closure coercion. Well, specifying the parameter is not necessary either as you are not handling it.
The last statement basically means than any method called on mockService will execute the specified closure, so empty list will be returned in result.
Simpler is better, cheers!
By the way, when using Spock you can still use coercion mocks. Spock mocks (created with Mock() method) are useful for testing more advanced cases, like for example interactions.
UPDATE: for integration test you would extend IntegrationSpec and no use of @TestFor will be necessary.