如何在Junit中使用slf4j模拟log4j2 logger对象

时间:2018-02-21 04:12:21

标签: spring-boot junit kotlin slf4j log4j2

我有以下代码,我使用slf4j工厂创建不同的log4j2记录器对象,我需要根据输入参数写入特定的日志文件。

@Service
class WriterService {

val logger1: Logger = LoggerFactory.getLogger("t_logger")
val logger2: Logger = LoggerFactory.getLogger("b_logger")
val labelKey = "Label"

fun writeLog(payload: Map<String, Any>){

    if(payload.containsKey(labelKey)) {

        val label = payload[labelKey].toString().toLowerCase()

        if (label == "t") {
            logger1.info("{}", payload)

        } else if (label == "b") {
            logger2.info("{}", payload)
        }
    }
}

我想知道如何使用MockitoJUnitRunner模拟Logger对象,以便我可以模拟调用哪个logger对象?

1 个答案:

答案 0 :(得分:0)

我使用Appender和ArgumentCaptor找到了解决方案...... 以下针对可能感兴趣的人的解决方案...

import org.apache.logging.log4j.Level
import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.core.Appender
import org.apache.logging.log4j.core.LogEvent
import org.apache.logging.log4j.core.Logger
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.Captor
import org.mockito.InjectMocks
import org.mockito.Mock
import org.mockito.Mockito.*
import org.mockito.runners.MockitoJUnitRunner
import java.lang.StringBuilder

@RunWith(MockitoJUnitRunner::class)
class ServiceTest {

    @InjectMocks
    var service: WriterService 

    @Mock
    private val mockAppender: Appender? = null

    @Captor
    private val captorLoggingEvent: ArgumentCaptor<LogEvent>? = null

    private var logger1: Logger? = null
    private var logger2: Logger? = null

    @Before
    fun setup() {
        `when`(mockAppender!!.name).thenReturn("MockAppender")
        `when`(mockAppender.isStarted).thenReturn(true)
        `when`(mockAppender.isStopped).thenReturn(false)

        logger1 = LogManager.getLogger("t_logger") as Logger
        logger1!!.addAppender(mockAppender)
        logger1!!.level = Level.INFO

        logger2 = LogManager.getLogger("b_logger") as Logger
        logger2!!.addAppender(mockAppender)
        logger2!!.level = Level.INFO
    }

    @After
    fun tearDown() {
        logger1!!.removeAppender(mockAppender!!)
        logger2!!.removeAppender(mockAppender!!)
    }

    @Test
    fun writeLog_shouldWriteTransactionLogWhenLabelIs_T() {

        val payload = hashMapOf("Label" to "t")

        service.writeLog(payload)

        verify(mockAppender, times(1))!!.append(captorLoggingEvent!!.capture())
        assertEquals(captorLoggingEvent.value.level, Level.INFO)
        assertEquals(captorLoggingEvent.value.loggerName, "t_logger")
        assertEquals(captorLoggingEvent.value.message.formattedMessage, "{Label=t}")
    }

    @Test
    fun writeLog_shouldWriteBackendLogWhenLabelIs_B() {

        val payload = hashMapOf("Label" to "b")

        service.writeLog(payload)

        verify(mockAppender, times(1))!!.append(captorLoggingEvent!!.capture())
        assertEquals(captorLoggingEvent.value.level, Level.INFO)
        assertEquals(captorLoggingEvent.value.loggerName, "b_logger")
        assertEquals(captorLoggingEvent.value.message.formattedMessage, "{Label=b}")
    }
}