使用 Mockito 对 LazyLogging 进行单元测试

Unit test LazyLogging using Mockito

我有一个 class 扩展了 LazyLogging 特征

class TaskProcessor()
  extends Processor
    with LazyLogging {

  def a1() = {
    logger.info("Test logging")
  }
}

现在,我想测试一下我的日志记录是否有效。所以我按照这个例子 Unit test logger messages using specs2 + scalalogging 写了我的测试如下

 "TaskProcessor" should "test logging" in {

    val mockLogger = mock[Logger]
    val testable = new TaskProcessor {
      override val logger: Logger = mockLogger
    }
    verify(mockLogger).info("Test logging")
}

我收到以下错误

Error:(32, 20) overriding lazy value logger in trait LazyLogging of type com.typesafe.scalalogging.Logger;
 value logger must be declared lazy to override a concrete lazy value
      override val logger: Logger = mockLogger

为了解决这个问题,我修改了语句

  override val logger: Logger = mockLogger

  override lazy val logger: Logger = mockLogger

我收到以下错误

Cannot mock/spy class com.typesafe.scalalogging.Logger
Mockito cannot mock/spy following:
  - final classes
  - anonymous classes
  - primitive types
org.mockito.exceptions.base.MockitoException: 
Cannot mock/spy class com.typesafe.scalalogging.Logger
Mockito cannot mock/spy following:
  - final classes
  - anonymous classes
  - primitive types
    at org.scalatest.mockito.MockitoSugar.mock(MockitoSugar.scala:73)
    at org.scalatest.mockito.MockitoSugar.mock$(MockitoSugar.scala:72)

我的家属如下

 "org.scalatest" %% "scalatest" % "3.0.5" % "test",
  "org.mockito" % "mockito-all" % "1.10.19" % Test,
  "com.typesafe.scala-logging" %% "scala-logging" % "3.9.2",

任何人都可以指导我如何模拟记录器并进行测试。

问题是 com.typesafe.scalalogging.Logger class 不能被模拟,因为它是最终的,但我们仍然可以模拟底层 org.slf4j.Logger.

import org.scalatest.mockito.MockitoSugar
import org.slf4j.{Logger => UnderlyingLogger}
import com.typesafe.scalalogging.Logger
import org.scalatest.{Matchers, WordSpec, FlatSpec}
import org.mockito.Mockito._

class TaskProcessorSpec extends FlatSpec with Matchers with MockitoSugar {

  "TaskProcessor" should "test logging" in {

    val mockLogger = mock[UnderlyingLogger]
    when(mockLogger.isInfoEnabled).thenReturn(true)

    val testable = new TaskProcessor {
      override lazy val logger = Logger(mockLogger)
    }
    testable.a1()

    verify(mockLogger).info("Test logging")
  }
}