1

私は遊びを持っています!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 {}

しかし、サービスの初期化さえ失敗します。

4

1 に答える 1

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)

これは、ログ メッセージが文字列ではなく、名前による引数 (したがって匿名関数) として渡されることが原因です。詳細については、この質問を参照してください。

于 2012-08-31T07:10:20.313 に答える