views:

373

answers:

2

I need to mock a GrailsControllerClass interface. Instance should have a static variable defined. The problem is that MockFor and StubFor don’t give you an option for adding static members. So, I write my abstract class that extends GrailsControllerClass

abstract class MyController implements GrailsControllerClass {
   static myDefinition  = [name:"item1", action:"action1"]
}

Now, MockFor and StubFor raise an error: groovy.lang.MissingMethodException: No signature of method: groovy.util.ProxyGenerator.instantiateAggregateFromBaseClass() is applicable for argument types: (java.lang.Class, null) values… which seems to be a reported bug: http://jira.codehaus.org/browse/GROOVY-3720 Alas, grails comes with groovy 1.6.

I do not want to make MyController a huge concrete class with empty method declarations. Any alternatives?

A: 

Have you tried GMock, yet? It supports mocking of static methods.

Christoph Metzendorf
I would like my tests to extend GrailsTestCase, so that I can use grails test runner. While it seems you can use @WithGMock annotation, it seems that your assertions have to be enclosed inside play{}. It seems to me that gmock is more than mocking fwk..
Dan
Yes, GMock is more sophisticated than standard Groovy MockFor or StubFor, but it's still a mocking framework and nothing more IMO. The execution part of your test has to be inside the play closure, which separates the setting of expectations and adding of behaviour from the execution. This is somewhat similar to what EasyMock does, but it feels more natural.Yes, you're right, if you want to extend GrailsUnitTestCase instead of GMockTestCase, then you have to use the @WithGMock annotation.
Christoph Metzendorf
A: 

You could tweak the metaClass I believe:

GrailsControllerClass.metaClass.'static'.myDefinition = [name:"item1", action:"action1"]

Or use a map to mock your controller interface:

def myController = [getMyDefinition:{[name:"item1", action:"action1"]}] as GrailsControllerClass

I'm not sure based on your post if that's what you're looking for or not.

Matt Lachman
doesn't seem to work for static fields: GrailsControllerClass.metaClass.'static'.myDefinition = [name:"item1", action:"action1"]
Dan
Yes, I'm seeing some difficulty with static fields in my own post here: http://stackoverflow.com/questions/1707830/using-groovy-metaclass-to-mock-out-shiro-securityutils-in-bootstrap. I wonder if it's possibly related to this bug: http://jira.codehaus.org/browse/GROOVY-3873?
Matt Lachman