2016-06-30 23 views
1

下面是我試圖寫JUnit測試的方法:測試使用Junit調用Logback Log統計信息?

方法我想測試:

//logger declared outside of method in Class 
    private static Logger LOGGER = LoggerFactory.getLogger(PersonService.class); 

    public void showOutputOfIdentifications(int age) { 

     if(age>25){ 

      LOGGER.info("Over 25"); 

     }else{ 

      LOGGER.info("25 or Under"); 

     } 
    } 

如何測試,以驗證正確的Logback日誌語句已被稱爲?

在我的測試中,我試圖模擬logger並驗證它是否被調用,但是這不起作用?

電流測試嘗試:

@Test 
    public void testShowOutputOfIdentifications() throws ParseException{ 

    int age = 10; 

    Logger LOGGER_mock = mock(Logger.class); 

    //call method under test 
    showOutputOfIdentifications(age); 

    verify(LOGGER_mock).info("25 or under"); 


} 

當前失敗的測試輸出:

Wanted but not invoked: 
logger.info(
    "25 or under " 
); 

Actually, there were zero interactions with this mock. 
+2

被測試的類可能有一個使用的靜態記錄器LOGGER。你必須注入你的模擬器作爲記錄器。創建另一個記錄器不會被調用。 – Fildor

+0

謝謝,請舉出這個例子,我編輯了原始的方法來顯示我的靜態記錄器# – java123999

+0

關鍵是:你需要**控制你的「正在測試的代碼」使用的對象。如果你有一個工廠爲你創建一個對象,然後這個對象被分配到你的類中,你無法控制。 – GhostCat

回答

2

你可以添加自己的appender並斷言日誌消息寫入這樣一來,看到Programmatically configure LogBack appender

事情是這樣的:

// create the mock appender 
Appender mockedAppender = Mockito.mock(Appender.class); 

// inject it 
((ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME)).addAppender(mockedAppender); 

// run your test 
LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME).error("Test msg"); 

// verify using ArgumentCaptor 
ArgumentCaptor<Appender> argumentCaptor = ArgumentCaptor.forClass(Appender.class); 
Mockito.verify(mockedAppender).doAppend(argumentCaptor.capture()); 

// assert against argumentCaptor.getAllValues() 
Assert.assertEquals(1, argumentCaptor.getAllValues().size()); 
Assert.assertEquals("Test msg", ((LoggingEvent)argumentCaptor.getAllValues().get(0)).getMessage()); 

// remove the mock appender from static context 
((Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME)).detachAppender(mockedAppender); 
+0

謝謝,所以我寫了appender的實際記錄器或模擬? – java123999

+0

在先前的一篇文章中,我曾告訴你**在課堂上注入模擬測試。如果你沒有魔法會讓它被使用... –

+0

謝謝你能請你展示這個代碼示例嗎? – java123999

0

我寫這個使用Groovy和Spock嘲笑追加程序。

我的logback-的test.xml文件看起來像

<configuration debug="true"> 
<statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener"/> 
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> 
    <encoder> 
     <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> 
    </encoder> 
</appender> 

<appender name="JSON" class="ch.qos.logback.core.ConsoleAppender"> 
    <encoder> 
     <pattern>%msg%n</pattern> 
    </encoder> 
</appender> 

<logger name="clicks" level="INFO" additivity="false"> 
    <appender-ref ref="JSON"/> 
</logger> 
<logger name="com.carsnip" level="DEBUG"/> 

<root level="INFO"> 
    <appender-ref ref="STDOUT"/> 
</root> 

而且我的測試包括:

class LogTest extends Specification{ 
    def "should log"() { 
     given: 
     Logger root = (Logger) 
     LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); 
     Appender rootMockAppender = Mock() 
     root.addAppender(rootMockAppender); 
     Logger click = (Logger) LoggerFactory.getLogger("clicks"); 
     Appender clickMockAppender = Mock() 
     click.addAppender(clickMockAppender); 

     when: 
     click.info("HEYYYYY") 

    then: 
     0 * rootMockAppender.doAppend(_) 
     1 * clickMockAppender.doAppend(_) 
    } 
} 

這是寫檢查加屬性,以便於根記錄器,在層次結構中較高的層不會從我們的點擊記錄器獲取日誌,這些記錄器將轉到不同的位置。