Oops I forgot I have some logging inside my CachingService class. At runtime Grails auto-magically injects a "log" property into service classes. If my test was an integration test then there wouldn't be a problem. So I have two options, either mock out the logger or run my test as an integration tests. I decided to mock out the logger, which required me to do the following:
1. Create a MockLogger class (primarily since I will probably have to mock out the logger in other classes in the future)
class MockLogger {
void info(message) {}
void warn(message) {}
void debug(message) {}
void error(message) {}
}
2. Inject my MockLogger as a property named "log" via getLog() into my service class via ExpandoMetaClass
void setUp() {
CachingService.metaClass.getLog = { -> new MockLogger() }
}
3. Reset the state of CachingService before dynamically adding the property "log"
void tearDown() {
def remove = GroovySystem.metaClassRegistry.&removeMetaClass
remove CachingService
}
There may be other ways to mock out the logger, but this approach seemed simple enough. Do you have an easier approach? If so please drop a comment.
3 comments:
Nice post Scott. I had to deal with this recently too and used an Expando for the mock log. Saves a class def. Something like:
def logger = new Expando( debug: { println it }, info: { println it },
warn: { println it }, error: { println it } )
YourService.metaClass.getLog = { -> logger }
Though, obviously you could drop the printlns if you don't want to see the logs.
Just another technique..
I ended up doing this in the setup...
BasicConfigurator.configure()
LogManager.rootLogger.level = Level.DEBUG
log = LogManager.getLogger("MyService")
// use groovy metaClass to put the log
// into your class
MyService.class.metaClass.getLog << {-> log}
I blogged about it here:
logging in test
... don't know if that's very Groovy or not. Requires import of org.apache.log4j.*
Scott,
I have tried this & it works great if I have one test.
If I have 2 tests in the same class then the second test gets its log messages printed out twice. Any thoughts please ?
Post a Comment