14
votes

I've got few issues with Grails logging during test [running grails test-app, Grails 1.3.5]:

1

I've got some debug/info logging in my application and it works fine when running the app [grails run-app]. However when I want to test my app, none of it is written to the System.out/System.err files nor to file appender. How can I enable it?

I've got log.debug() and log.info() lines in my domain classes. in controllers and in classes located in src/groovy.

When I wanted to enable logging during test I just copied settings from my dev environment, and changed root logger from info to debug:

    appenders {
        file name: 'file', file: 'mylog.log'
    }

    root {
        debug 'stdout', 'file'
    }

    debug 'grails.app'


    error 'org.codehaus.groovy.grails.web.servlet',  //  controllers
            'org.codehaus.groovy.grails.web.pages', //  GSP
            'org.codehaus.groovy.grails.web.sitemesh', //  layouts
            'org.codehaus.groovy.grails.web.mapping.filter', // URL mapping
            'org.codehaus.groovy.grails.web.mapping', // URL mapping
            'org.codehaus.groovy.grails.commons', // core / classloading
            'org.codehaus.groovy.grails.plugins', // plugins
            'org.codehaus.groovy.grails.orm.hibernate', // hibernate integration
            'org.springframework',
            'org.hibernate',
            'net.sf.ehcache.hibernate'

    warn 'org.mortbay.log'

As I've said earlier. Everything works fine if I run the app in dev environment. It's only the test that I cannot see my logs.

Something to mention here: I can see my log.info() lines specified in the Test classes.

2 I cannot specify log.debug in Test classes. I'm getting missing method exception when trying to do log.debug. log.info works just fine. How come? I thought it's the same injection as within controllers/domains.

3 All information logged in Test classes during test are sent to System.err instead of System.out. Is grails even using the log4j configuration from Config.groovy?

Thanks in advance, Krystian

2

2 Answers

5
votes

what I do is just define my own logger and inject it into the controller or service in my test case.

    BasicConfigurator.configure() 
    LogManager.rootLogger.level = Level.DEBUG
    log = LogManager.getLogger("MailService")

    MailService.class.metaClass.getLog << {-> log}

I do not believe the log property is injected into test classes

I have also done this before which turned out to be more of a hack but worked

    def logger = new Expando(
            debug: { println it },
            info: { println it },
            warn: { println it },
            error: { println it })
    MailService.metaClass.getLog = {-> logger }
    MailServiceService.metaClass.getLog = {-> logger }
    MailIngestJobTests.metaClass.getLog = {-> logger }

Final Code Solution Here

1
votes

I think that you might want to use something like:

mockLogging(Foo, true)

Where Foo is a domain, service, etc.

This will write log.debug messages to your console. Just try to remove it before doing any reports, since they will become looooooong :)