Конфигурация Grails log4j

У меня неоднократно возникали проблемы с DSL, представленным Grails в версии 1.1 для настройки Log4J. Моя текущая конфигурация выглядит так:

log4j = {        
    debug 'com.mypackages'

    appenders {
        console name: 'stdout', layout: pattern(conversionPattern: '%d{dd-MM-yyyy HH:mm:ss,SSS} %5p %c{1} - %m%n')
        rollingFile name: 'hibeFile', file: "hibeFile", maxFileSize: '500KB'
    }

    // By default, messages are logged at the error level to both the console and hibeFile
    root {
        error 'stdout', 'hibeFile'
        additivity = true
    }
}

Намерение здесь такое:

  • Журнал com.mypackages на уровне отладки и все остальные на уровне ошибки
  • Записывать все выходные данные в файл с именем hibeFile и в консоль.

Это отлично работает, когда я запускаю приложение или интеграционные тесты. Однако, когда я запускаю модульные тесты, журнал не отображается ни в консоли, ни в ссылках «System.out» или «System.err», показанных в отчете о тестировании Grails. Как я могу увидеть свои журналы при выполнении модульных тестов?

Спасибо, Дон


person Dónal    schedule 19.11.2009    source источник


Ответы (3)


Насколько я знаю, при запуске модульного теста Grails вся регистрация недоступна через log4j, вызовы log.xxxx в классах домена и т. д. просто издеваются с использованием

mockLogging(ClassUnderTest, true)

«Истина» означает «включить отладку». Для этого класс модульного теста должен расширять GrailsUnitTestCase. Если вы используете mockController(class), он неявно вызывает mockLogging(class, false) и, следовательно, вы не получаете журнал отладки. Для получения дополнительной информации ознакомьтесь с исходными кодами Grails, например GrailsUnitTestCase и MockUtils.

В отличие от вышесказанного, в интеграционном тесте запускается весь механизм и доступен log4j.

person Stefan Armbruster    schedule 24.11.2009
comment
так как же протестировать контроллер, заваленный операторами ведения журнала? У меня сейчас такая проблема?? - person Aaron Saunders; 17.12.2009
comment
используйте mockLogging(MyDamnCoolCONtroller, true) в методе setUp() вашего теста. - person Stefan Armbruster; 17.12.2009

Вот мысль, вы не спрашивали именно об этом, но тот же вопрос был задан в группе пользователей Grails. Я также размещаю свой ответ здесь, чтобы распространять знания.

Если вы явно указываете def log = org.apache.commons.logging.LogFactory.getLog(this) в своих классах, а не полагаетесь на внедрение зависимостей, как было объяснено в группе пользователей Grails, вы можете имитировать getLog на LogFactory.

Приведенное ниже взято из grails.tests.MockUtils.mockLogging и изменено для возврата регистратора.

class LoggingEnabledTestCase extends GrailsUnitTestCase {
protected void setUp() {
        super.setUp()
        registerMetaClass(org.apache.commons.logging.LogFactory)
        org.apache.commons.logging.LogFactory.metaClass.'static'.getLog = {instance ->

            // This is taken from grails.tests.MockUtils and slightly changed to return a logger.

            // Get the name of the class + the last component of the package
            // (if it the class is in a package).
            def pos = instance.class.name.lastIndexOf('.')
            if (pos != -1) pos = instance.class.name.lastIndexOf('.', pos - 1)
            def shortName = instance.class.name.substring(pos + 1)

            // Dynamically inject a mock logger that simply prints the
            // log message (and optional exception) to stdout.
            def mockLogger = [
                    fatal: {String msg, Throwable t = null ->
                        println "FATAL (${shortName}): $msg"
                        if (t) {
                            println "       Exception thrown - ${t.message}"
                        }
                    },
                    error: {String msg, Throwable t = null ->
                        println "ERROR (${shortName}): $msg"
                        if (t) {
                            println "       Exception thrown - ${t.message}"
                        }
                    },
                    warn: {String msg, Throwable t = null ->
                        println "WARN (${shortName}):  $msg"
                        if (t) {
                            println "       Exception thrown - ${t.message}"
                        }
                    },
                    info: {String msg, Throwable t = null ->
                        println "INFO (${shortName}):  $msg"
                        if (t) {
                            println "       Exception thrown - ${t.message}"
                        }
                    },
                    debug: {String msg, Throwable t = null ->
                        println "DEBUG (${shortName}): $msg"
                        if (t) {
                            println "       Exception thrown - ${t.message}"
                        }
                    },
                    trace: {String msg, Throwable t = null -> },
                    isFatalEnabled: {-> true},
                    isErrorEnabled: {-> true},
                    isWarnEnabled: {-> true},
                    isInfoEnabled: {-> true},
                    isDebugEnabled: {-> true},
                    isTraceEnabled: {-> false}] as Log
            return mockLogger
        }
    }

    protected void tearDown() {
        super.tearDown()
    }
}
person Ben Doerr    schedule 24.11.2009

Используя Grails 1.1.1 и приближенную к вашей настройке, у меня есть модульный тест под названием FooTests.groovy

После запуска grails test-app я могу увидеть результат теста в каталоге:

./test/reports/plain

конкретно в файлах, по мере необходимости:

TEST-com.mypackages.FooTests-err.txt
TEST-com.mypackages.FooTests-out.txt
TEST-com.mypackages.FooTests.txt

Обратите внимание, что я не вижу вывода в файле hibeFile. Я не уверен, но я подозреваю, что предыдущий постер верен в том, что модульные тесты не получают настройку ведения журнала.

person Michael Easter    schedule 28.11.2009