I'm trying to mock a call to an outside service in an integration test, the service is used in a grails webflow. The service isn't in flow or conversation scope, but is added via dependency injection see here.
I've managed to figure out a way to override a service via replacing it's metaClass using ExpandoMetaClass. The changes only work when the test is ran alone, if another test that uses that same service is ran before this test, the metaClass changes are gone.
Part that overrides the metaClass:
static {
ExpandoMetaClass someService = new ExpandoMetaClass(Object, false)
someService.invokeMethod = { String name, args ->
def result = 'success'
if(name.equals('accessAnotherSystem')
{
StackTraceUtils.sanitize(new Throwable()).stackTrace.each
{
if(it.methodName.equals('test_method_I_Want_failure_in')
{
result = 'exception'
}
}
return result
}
def validMethod = SomeService.metaClass.getMetaMethod(name, args)
if (validMethod != null)
{
validMethod.invoke(delegate, args)
}
else
{
SomeService.metaClass.invokeMissingMethod(delegate, name, args)
}
}
someService.initialize()
SomeService.metaClass = someService
}
Related question: How to change a class's metaClass per test
Is there a way to keep my changes for the test, or is there some other way to override the service.