2009-11-19 138 views
1

我已經多次遇到由Grails在版本1.1中爲配置Log4J而引入的DSL問題。我現在的配置是這樣的:Grails 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文件控制檯

這工作正常,當我運行應用程序或集成測試。但是,當我運行單元測試時,控制檯或Grails測試報告中顯示的「System.out」或「System.err」鏈接中不會顯示任何日誌記錄。如何在運行單元測試時看到我的日誌?

謝謝, 唐

回答

2

據我所知,運行一個Grails單元測試時,整個日誌記錄不通過log4j的提供,在域類等log.xxxx調用中使用的只是嘲笑

mockLogging(ClassUnderTest, true) 

「真」表示「啓用調試」。爲此,單元測試類必須擴展GrailsUnitTestCase。 如果你使用mockController(class),它會隱式地調用mockLogging(class,false),因此你不會得到調試日誌。有關詳細信息,請查看grails源代碼,特別是GrailsUnitTestCase和MockUtils。

與上述相反,在集成測試中,整個機器啓動並且log4j可用。

+0

那麼如何測試一個充滿日誌語句的控制器呢?我現在有這個問題? – 2009-12-17 02:54:02

+0

在測試的setUp()方法中使用mockLogging(MyDamnCoolCOntroller,true)。 – 2009-12-17 13:18:55

1

這是一個想法,你沒有問完全這個問題,但在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() 
    } 
} 
0

使用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中看不到輸出。我不確定,但我懷疑之前的海報是正確的,因爲單元測試沒有收到日誌記錄設置。