Unit test LazyLogging using Mockito

Viewed 1148

I am having a class which extends LazyLogging trait

class TaskProcessor()
  extends Processor
    with LazyLogging {

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

Now, I want to test whether my logging works. So I followed this example Unit test logger messages using specs2 + scalalogging and wrote my test as follows

 "TaskProcessor" should "test logging" in {

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

I get the following error

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

To resolve this, I modify statement

  override val logger: Logger = mockLogger

to

  override lazy val logger: Logger = mockLogger

I get the following error

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)

My dependecies are as follows

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

Can anyone please guide me as to how I can mock the logger and do the testing.

1 Answers

The problem is that com.typesafe.scalalogging.Logger class cannot be mocked because it's final, but we still can mock underlying 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")
  }
}
Related