使用LogCaptor对日志进行单元测试

1 为什么要对日志进行单元测试

对代码中打印的日志,是否有必要通过单元测试保证日志的格式、内容能够被正确的修改?答案是在一般情况下都无需对日志的格式、内容进行单元测试。那么在什么场景下,通过单元测试看护日志的格式、内容是有必要的呢?在日志作为系统的输入时(告警、统计系统等),为了保证其他系统的正确运行,日志的格式、内容保持不变就非常的有必要。还有一点就是这些作为其他系统输入的日志和普通的信息、错误记录日志并没有不同,在开发过程中往往修改起来比较随意,增加单元测试可以提高相关日志的重要性,再修改了日志后可以及时通知其他系统进行调整,避免出现不必要的恐慌。

2 使用LogCaptor对日志测试

文章中的源码可以从:https://github.com/ctlove0523/java-samples 获取

2.1 安装LogCaptor


    io.github.hakky54
    logcaptor
    2.7.8
    test

LogCaptor项目地址:https://github.com/Hakky54/log-captor

2.2 测试类

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LogCaptorService {
    private static final Logger log = LoggerFactory.getLogger(LogCaptorService.class);

    public void commonLog() {
        log.debug("log captor debug log");
        log.info("log captor info log");
        log.warn("log captor warn log");
        log.error("log captor error log");
    }

    public void oddNumber(int number) {
        if (number % 2 == 1) {
            log.info("input is odd number");
        }

        log.info("input is even number");
    }

    public void logSwitch() {
        if (log.isDebugEnabled()) {
            log.debug("log enable debug");
        }

        log.info("log enable info");
    }
}

2.3 捕获日志

import static org.assertj.core.api.Assertions.assertThat;
import nl.altindag.log.LogCaptor;
import org.junit.Test;

public class CommonLogTest {

    @Test
    public void testCommonLog_should_logMessage() {
        LogCaptorService logCaptorService = new LogCaptorService();
        LogCaptor logCaptor = LogCaptor.forClass(LogCaptorService.class);

        logCaptorService.commonLog();

        assertThat(logCaptor.getDebugLogs()).containsExactly("log captor debug log");
        assertThat(logCaptor.getInfoLogs()).containsExactly("log captor info log");
        assertThat(logCaptor.getWarnLogs()).containsExactly("log captor warn log");
        assertThat(logCaptor.getErrorLogs()).containsExactly("log captor error log");
        assertThat(logCaptor.getLogs().size()).isEqualTo(4);
    }
}

2.4 重用LogCaptor

import static org.assertj.core.api.Assertions.assertThat;
import nl.altindag.log.LogCaptor;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

public class ReuseLogCaptorTest {
    private static LogCaptor logCaptor;

    @BeforeClass
    public static void init() {
        logCaptor = LogCaptor.forClass(LogCaptorService.class);
    }

    @Before
    public void cleanLogs() {
        logCaptor.clearLogs();
    }

    @AfterClass
    public static void close() {
        logCaptor.close();
    }

    @Test
    public void testOddNumber_should_logOddMsg_when_inputIsOddNumber() {
        LogCaptor logCaptor = LogCaptor.forClass(LogCaptorService.class);
        LogCaptorService logCaptorService = new LogCaptorService();

        logCaptorService.oddNumber(1);

        assertThat(logCaptor.getInfoLogs()).containsExactly("input is odd number");
        assertThat(logCaptor.getLogs().size()).isEqualTo(1);
    }

    @Test
    public void testOddNumber_should_logEvenMsg_when_inputIsEvenNumber() {
        LogCaptor logCaptor = LogCaptor.forClass(LogCaptorService.class);
        LogCaptorService logCaptorService = new LogCaptorService();

        logCaptorService.oddNumber(2);

        assertThat(logCaptor.getInfoLogs()).containsExactly("input is even number");
        assertThat(logCaptor.getLogs().size()).isEqualTo(1);
    }
}

2.5 测试带有开关的日志

import static org.assertj.core.api.Assertions.assertThat;
import nl.altindag.log.LogCaptor;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

public class LogSwitchTest {
    private static LogCaptor logCaptor;

    @BeforeClass
    public static void init() {
        logCaptor = LogCaptor.forClass(LogCaptorService.class);
    }

    @Before
    public void cleanLogs() {
        logCaptor.clearLogs();
    }

    @AfterClass
    public static void close() {
        logCaptor.close();
    }

    @Test
    public void testLogSwitch_should_notLogDebugMsg_when_logInfoOn() {
        LogCaptorService logCaptorService = new LogCaptorService();
        logCaptor.setLogLevelToInfo();

        logCaptorService.logSwitch();

        assertThat(logCaptor.getInfoLogs()).containsExactly("log enable info");
        assertThat(logCaptor.getLogs().size()).isEqualTo(1);
    }

    @Test
    public void testLogSwitch_should_logDebugMsg_when_logDebugOn() {
        LogCaptorService logCaptorService = new LogCaptorService();
        logCaptor.setLogLevelToDebug();

        logCaptorService.logSwitch();

        assertThat(logCaptor.getInfoLogs()).containsExactly("log enable info");
        assertThat(logCaptor.getDebugLogs()).containsExactly("log enable debug");
        assertThat(logCaptor.getLogs().size()).isEqualTo(2);
    }
}

你可能感兴趣的:(使用LogCaptor对日志进行单元测试)