如何在 Junit 中使用 slf4j 模拟 log4j2 记录器对象
Posted
技术标签:
【中文标题】如何在 Junit 中使用 slf4j 模拟 log4j2 记录器对象【英文标题】:How to mock log4j2 logger object using slf4j in Junit 【发布时间】:2018-07-31 13:41:03 【问题描述】:我在下面的代码中使用 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 对象,以便模拟调用了哪个记录器对象?
【问题讨论】:
【参考方案1】:我找到了使用 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")
【讨论】:
以上是关于如何在 Junit 中使用 slf4j 模拟 log4j2 记录器对象的主要内容,如果未能解决你的问题,请参考以下文章
在 Intellij idea Ultimate2017.2 中运行 maven webapp 时出错:原因:java.lang.NoClassDefFoundError: Lorg/slf4j/Lo
Spring JUnit:如何在自动装配组件中模拟自动装配组件