我玩了! 2应用程序(Scala),我有一些类,当它们出错时需要执行日志记录。
我希望能够对这些日志记录操作实际发生在正确的条件下进行单元测试。为此,我需要能够模拟记录器,但我遇到了Mockito的一些问题。我拥有(简化)的样子
import play.api.{ Logger, LoggerLike }
trait BaseService {
val log: LoggerLike
def fail(reason: String) {
log.error(reason)
}
}
object Service extends BaseService {
val log = Logger
}
然后在测试中
import org.specs2.mutable._
import org.specs2.mock._
import services.BaseService
object Service extends BaseService with Mockito {
val log = mock[play.api.Logger]
def verify(key: String) = {
there was one(log).error(key)
}
}
class ServiceSpec extends Specification {
"failures should be logged" in {
Service.fail("foo")
Service.verify("foo")
}
}
但是我收到了错误
[error] NullPointerException: null (Logger.scala:43)
[error] play.api.LoggerLike$class.isErrorEnabled(Logger.scala:43)
[error] play.api.Logger.isErrorEnabled(Logger.scala:147)
[error] play.api.LoggerLike$class.error(Logger.scala:127)
[error] play.api.Logger.error(Logger.scala:147)
[error] services.BaseService$class.fail(Service.scala:19)
[error] Service$.fail(ServiceSpec.scala:11)
...
我尝试添加
log.isErrorEnabled returns true
log.error(any[String]) returns {}
但是,即使服务初始化失败。
答案 0 :(得分:1)
我不是Mockito专家,但我认为你的模拟器在这里出现故障,因为堆栈跟踪显示了被调用的实际播放Logger
方法。这很可能是因为你试图在这里嘲笑Scala object
。相反,如果你嘲笑像
val log = mock[play.api.LoggerLike]
您将通过此特定错误并转到下一个问题 - 您的验证无效:
[error] The mock was not called as expected:
[error] Argument(s) are different! Wanted:
[error] loggerLike.error(
[error] ($anonfun$apply$mcV$sp$1) <function0>
[error] );
[error] -> at Service$$anonfun$verify$1.apply$mcV$sp(ServiceSpec.scala:10)
[error] Actual invocation has different arguments:
[error] loggerLike.error(
[error] ($anonfun$fail$1) <function0>
[error] );
[error] -> at services.BaseService$class.fail(x.scala:57)
[error] (ServiceSpec.scala:17)
这是由于日志消息作为名称参数(以及匿名函数)而不是字符串传递的事实引起的,请参阅this question以进一步讨论。