2013-09-05 10 views
8

私はPlayフレームワークでscalaのユニットテストを試しています。 私は設定が(私はハンドリングもう少しエラーを持っているが、私は実際に今、私のテストのためにこのコードを使用)が正しいかどうかをチェックするクラスを書いた:Mockitoスカラ検証テストが機能しない(フレームワークを再生する)

class TaskQueueConfig(conf: Configuration) { 
    val schedulingEnabled = conf.getBoolean("schedulingEnabled").get 
    val processingEnabled = conf.getBoolean("processingEnabled").get 
    val queueName = conf.getString("queue").get 
} 

私はプレー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) 

コードは非常に孤立していると明らかにただ1つのconfにありますので、これは、非常に奇妙ですTaskQueueConfigの.getString呼び出し。 10行目はgetStringメソッドを使った行です。 61行目は「ある(tQConf).getString」という行です

この問題を解決するにはどうすればよいですか?

(との間には違いはなかった)。

PS:私はこの例はテストするのにはかなり役に立たないと知っていますが、テストする必要があるいくつかのルールがある場合はもっと複雑な設定があります。

UPDATE 1 getStringメソッドは、2つのパラメータがあり、第二パラメータなしのデフォルト値を有している(それのタイプはオプションである[セット[文字列]])。セットアップと検証に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を使用する必要がありますか?

+0

は、なぜあなたは今作成したオブジェクトの終了状態を検証する対モックコンフィグで呼ばれていたものを検証していますか?あなたが正しくスタブしていれば、 'TaskQueueConfig'のプロパティ値が設定したスタブ値と一致していることを確認してください。私はこれがあなたの質問に答えないことを知っていますが、それは確かにあなたのためにこの問題を排除するでしょう... – cmbaxter

+0

この特定のケースでは、もちろん、私はこれを持っていた大きな例から来て、可能な限り小さな例ですので、私にご負担ください! – Jaap

+0

私の最初の2つの考えは、スタブ自体がカウントされていた(したがって2回コールする)か、スコープの問題があり、もう1つのテストシーケンスもカウントされていたためです。私は最初の理論を自分でテストしましたが、mockitoが誤って呼び出しカウントにスタブを含めているように見えません。スコープの問題については、実際のコードがここにあるようなもので、モックがグローバルに作成されていない場合は、問題ではありません。 – cmbaxter

答えて

4

あなたはMockitoはのためにすべての引数または全てでなしを使用マッチャーを使用するか、あなたが必要なので、2つの引数getString()呼び出しでnullを使用する必要があります。

"queue"(リテラル)をany[Option[Set[String]]](マッチャー)と混ぜることはできません。

tqConf.getString(org.mockito.Matchers.eq("queue"), any[Option[Set[String]]]) returns Some("queueName") 

このようなすべての位置での照合プログラムを使用してみてください... は時々 Mockitoは、あなたがそれをやったことを作業することができ、それはあなたにエラーが発生しますが、あなたはここに不運いるように思えます

と検証:

there was one(tqConf).getString(eq("queue"), any[Option[Set[String]]]) 
+0

ありがとう!私はこれに関連するもう1つの質問があります。なぜtqConf.getString( "queue"、None)が返されるのか説明できますSome( "queueName")が機能しません。 getString( "queue")を呼び出すコードでNPEを取得しています。 getStringの2番目のオプションのパラメータのデフォルト値はありません。 – Jaap

+1

実際に面白いMockitoマッチャーとScalaのデフォルト引数のコーナーケース。 'tqConf.getString(" queue ")はSome(" queueName ")'を返します(つまり、デフォルトのargを完全に無視して、ちょうど1つのリテラルを直接使用します)。そして 'tqConf .getString(org.mockito.Matchers.eq( "queue")、任意の[Option [Set [String]]])はSome( "queueName")を返す(つまり、Mockito勧告と同様に_both_引数のマッチャーを使用する)。私はまだexplicitnessのために自分自身の第二のフォームを好むだろうが、それは面白いです... – millhouse

関連する問題