scala で Play フレームワークを使用して単体テストを試みています。構成が正しいかどうかをチェックするクラスを作成しました (もう少しエラー処理がありますが、実際にはこのコードをテストに使用しています)。
class TaskQueueConfig(conf: Configuration) {
val schedulingEnabled = conf.getBoolean("schedulingEnabled").get
val processingEnabled = conf.getBoolean("processingEnabled").get
val queueName = conf.getString("queue").get
}
play 2.1.1 のデフォルトのテスト設定を使ってこれをテストしています:
class ConfigTestSpec extends Specification with Mockito with CalledMatchers {
"TaskQueueConfig" should {
"verify calls" in {
val tqConf = mock[Configuration]
tqConf.getString("queue") returns Some("queueName")
tqConf.getBoolean("schedulingEnabled") returns Some(true)
tqConf.getBoolean("processingEnabled") returns Some(true)
Logger.error("setup done")
val config = new TaskQueueConfig(tqConf)
there was one(tqConf).getString("queue")
there were two(tqConf).getBoolean(any[String])
there were one(tqConf).getBoolean("schedulingEnabled")
there were one(tqConf).getBoolean("processingEnabled")
}
}
}
次のエラーが表示されます。
[error] x verify calls
[error] The mock was not called as expected:
[error] configuration.getString$default$2();
[error] Wanted 1 time:
[error] -> at config.ConfigTestSpec$$anonfun$2$$anonfun$apply$4$$anonfun$apply$12.apply(ConfigTestSpec.scala:61)
[error] But was 2 times. Undesired invocation:
[error] -> at config.TaskQueueConfig.<init>(TaskQueueConfig.scala:10) (ConfigTestSpec.scala:61)
コードは非常に分離されており、TaskQueueConfig には明らかに conf.getString 呼び出しが 1 つしかないため、これは非常に奇妙です。行 10 は、getString メソッドを含む行です。61 行目は「there was one(tQConf).getString」の行です。
この問題を解決するにはどうすればよいですか?
(あったとあったの間に違いはありません)。
PS: この例はテストするのにかなり役に立たないことはわかっていますが、テストする必要があるいくつかのルールがあるより複雑な構成があります。
UPDATE 1
getString メソッドには 2 つのパラメーターがあり、2 番目のパラメーターのデフォルト値は None です (タイプは Option[Set[String]])。None をセットアップと検証に明示的に追加しても、まだ機能しません。しかし、null
代わりに追加すると、機能します。
val tqConf = mock[Configuration]
tqConf.getString("queue", null) returns Some("queueName")
tqConf.getBoolean("schedulingEnabled") returns Some(true)
tqConf.getBoolean("processingEnabled") returns Some(true)
val c = new TaskQueueConfig(tqConf)
there was one(tqConf).getString("queue", null)
there was one(tqConf).getString(any[String], any[Option[Set[String]]])
there were two(tqConf).getBoolean(any[String])
there was one(tqConf).getBoolean("schedulingEnabled")
there was one(tqConf).getBoolean("processingEnabled")
c.processingEnabled must beTrue
c.schedulingEnabled must beTrue
c.queueName must be("queueName")
では、なぜ null を使用する必要があるのでしょうか。