I know there's a lot out there about this particular topic, however I can't quite find anyone who has stumbled across my issue, and hopefully someone can explain this to me.
I have a Domain where I use the injected grailsApplication's dynamic method 'isDomainClass' in the equals method:
@Override
public boolean equals(Object obj) {
if(!grailsApplication.isDomainClass(obj.getClass())) { return false }
...
}
This works fine, and to unit test this i do:
@Mock([MyDomain])
...
def mockGApp
void setUp() {
mockGApp = new Object()
mockGApp.metaClass.isDomainClass = { obj -> true }
}
...
void testSomething() {
def myDomain = new MyDomain()
myDomain.grailsApplication = mockGApp
....
}
And when I run this with test-app -unit (on command line or in STS) it passes just fine.
I then ave an integration test that uses that domain (no mocking this time) and that again runs fine when ran with test-app -integration (either on the command line or in STS)
However if i run 'test-app' so it does both at once, I get a MissingMethodException: no method signature isDomainClass exists with parameters (java.lang.Class) ...
and all that jazz.
On investigating it with println
's in the service I'm testing in the tests, in the integration portion of the testing, before the equals method of my domain class is called, I can quite happily call grailsApplication.isDomainClass()
and get the desired affect. However when the code steps into the domain's equals function the isDomainClass()
method no longer exists, despite the grailsApplication
object referring to the same object which is referenced in the service and has the dynamically added method.
It appears that the dynamic methods that grails adds to this class are not being injected when its called within the domain's methods but are getting injected within the service. And more bizarrely this only happens if the integration tests follow the unit tests. If done separately, no problemo...
Where does this pollution stem from? IS there any way to solve it?
P.S. using Grails 2.1.0
You have to remove the class you modified from metaClassRegistry in the destroy method (i.e.after test case runs). See below: