2013-05-12 11 views
12

私は、暗黙的なパラメータが関係しているときに、Scalaでテストを書く方法を理解しようとするのに苦労しています。暗黙的なパラメータを嘲笑するスカラテスト?

私は私のコードとテストの次(ショートバージョン)があります。

実装(Scalaの2.10を、スプレーしアッカ):(ScalaTestとMockito使用)

import spray.httpx.SprayJsonSupport._ 
import com.acme.ResultJsonFormat._ 

case class PerRequestIndexingActor(ctx: RequestContext) extends Actor with ActorLogging { 
    def receive = LoggingReceive { 
    case AddToIndexRequestCompleted(result) => 
     ctx.complete(result) 
     context.stop(self) 
    } 
} 


object ResultJsonFormat extends DefaultJsonProtocol { 
    implicit val resultFormat = jsonFormat2(Result) 
} 

case class Result(code: Int, message: String) 

テスト:

"Per Request Indexing Actor" should { 
    "send the HTTP Response when AddToIndexRequestCompleted message is received" in { 
     val request = mock[RequestContext] 
     val result = mock[Result] 

     val perRequestIndexingActor = TestActorRef(Props(new PerRequestIndexingActor(request))) 
     perRequestIndexingActor ! AddToIndexRequestCompleted(result) 

     verify(request).complete(result) 
    } 
    } 

この行のverify(request).complete(result)は、暗黙のMarshallerを使用してResultをJSONに変換します。

implicit val marshaller: Marshaller[Result] = mock[Marshaller[Result]]を追加することで、マーシャラーを追加することはできますが、テストを実行すると、Marshallerの別のインスタンスが使用されるため、検証に失敗します。

モックマーシャルを明示的にcompleteに渡しても、失敗します。

したがって、暗黙のパラメータ用の模擬オブジェクトを作成する方法をアドバイスし、インスタンスが使用されていることを確認することはできますか?

+0

モックを明示的に渡すのに失敗しますか?なぜモックマーシャラーを最初に使用したいのですか? (私はモチートを使っていないので、もしそれらが愚かな質問であれば私を容赦してください) – jrudolph

答えて

5

これは、MarshitoのargにMatcherのMockitoを使用するのに最適な状況です。暗黙のマーシャラーを模倣する必要はありません。本当にやりたかったのは、completeが呼び出されたことと、あなたが期待したものと一致するresultと、マーシャルアールのインスタンスとが一致していることを確認するだけです。

:あなたは結果に参照マッチングを望んでいた場合

import org.mockito.Matchers._ 

次に、あなたがそうのような検証ができます:まず、あなたはすでにそれを行っていない場合、Mockitoはそうのようなインポートをスコープにマッチャー持参

verify(request).complete(same(result))(any[classOf[Marshaller[Result]]]) 

または、あなたが望んでいた場合、あなたが行うことができ、結果に一致等しい:

verify(request).complete(eq(result))(any(classOf[Marshaller[Result]])) 

マッチャとのトリックを使用すると、1つの引数のための1つを使用したら、それが理由ですので、あなたは、すべての引数のためにそれらを使用する必要があります私たちは持っているo resultも1つを使用してください。

+0

私もそれを試していました。私は 'same()'マッチャーを使って試していませんでしたが。 'verify(request).complete(same(result))(任意の[classOf [Marshaller [Result]])')を使用したときにテストが合格するのはなぜ(まだ) ).complete(eq(result))(any(classOf [Marshaller [Result]])) '。あなたの提案をお寄せいただきありがとうございます:) – C0deAttack

+0

リクエスト変数はモックであり、eqマッチャーはスタブされていないequalsメソッドを使用するため、常にfalseとなり、一致しません。同じことがここにうまく当てはまる。リクエストがモックではなく、いくつかのケースクラスであった場合、eqはより良くフィットするかもしれません – cmbaxter

+1

フォローアップありがとうございます。明確でないことに対する謝罪。 'eq'を使うとテストはコンパイルされません。 'eq'を使用すると、エラーメッセージは「タイプの不一致、期待値:Marshaller [ブール]、実際:Marshaller [結果]」となります。そして、それは 'any(classOf [Marshaller [Result]])'のエラーです。私はエラーがなぜ発生するのかについて100%明確ではありませんか?かなり奇妙です。 – C0deAttack

関連する問題