2013-01-11 25 views
5

完全な開示:私はフレームワークを嘲笑し、嘲笑することにとても新しいです。私はScalaMockを使用しようとしています。なぜなら、ScalaTestで使用する 'デフォルトの'モッキングフレームワークのように思えますが、ScalaTestと互換性のある他のフレームワークを使用しています。ScalaMock。引数を取るクラスをモックする

問題:私はScalaでソケットと会話するクラスを作成しました。クラスには、どの種類のソケットと通信するかという型パラメータがあります。その引数の1つは、その型のソケットを作成するためのファクトリです。これは、シグネチャがあります。

class XScanner[T <: SocketClient](
    confPath: String = "/etc/default/configPath", 
    socketClientFactory: String => T 
) extends ScannerBase(path) 

私は私のテストコードは、実際のソケットに接続する必要はありませんが、私は働くことができないので、モックSocketClientを供給することにより、このクラスのユニットテストを書くことができるようにしたいと思いますScalaMockでこれを行う方法。

私のテストコードは次のようになります。SocketClientは、引数としてソケットへのパスを想定しているためコンパイルされませんが、それはタイプではないので、私はmock[SocketClient(s)]を呼び出すことはできませんし、私ができる明らかに

val t = new XScanner[SocketClient](confPath, (s: String) => mock[SocketClient]) 

mock[SocketClient](s)を呼び出してください。mockは渡された型の引数をそれ自身の引数として取っていないからです。

私はスキャナを渡す工場SocketClientをどのように書くことができますか?私は引数を取るクラスを模擬する方法を試すことさえできません!

+0

私はScalaMockの著者です。 ScalaのどのバージョンとScalaMockのバージョンを使用していますか? ScalaMock2とScalaMock3の回答は異なります。 –

+0

Scala Mock 3 with Scala 2.10.0 – jangoolie

答えて

3

あなたが模擬する必要があるのはsocketClientFactoryです。そして、それを設定して、モックSocketClientを返します。

は考える:

trait SocketClient { 
    def frobnicate(): Unit 
} 

class ScannerBase(path: String) 

class XScanner[T <: SocketClient](
    confPath: String = "/etc/default/configPath", 
    socketClientFactory: String => T 
) extends ScannerBase(confPath) { 
    val socket = socketClientFactory("Some Socket Name") 
    socket.frobnicate 
} 

(サイドノート - socketClientFactoryにはデフォルト値はありませんのでconfPathためのデフォルト値を使用することはできません)。

は、これはあなたが始める必要があります(これはScalaの2.9.xとであるScalaMock2 - ScalaMock3と2.10.xは若干異なりますが、あまりないので):完全性については

import org.scalatest.FunSuite 
import org.scalamock.scalatest.MockFactory 
import org.scalamock.generated.GeneratedMockFactory 

class ScannerTest extends FunSuite with MockFactory with GeneratedMockFactory { 

    test("scanner") { 
    val mockFactory = mockFunction[String, SocketClient] 
    val mockClient = mock[SocketClient] 
    mockFactory.expects("Some Socket Name").returning(mockClient) 
    mockClient.expects.frobnicate 
    val scanner = new XScanner("path/to/config", mockFactory) 
    } 
} 

は、ここでは同じですScala 2.10.0とScalaMock3のテスト:

import org.scalatest.FunSuite 
import org.scalamock.scalatest.MockFactory 

class ScannerTest extends FunSuite with MockFactory { 

    test("scanner") { 
    val mockFactory = mockFunction[String, SocketClient] 
    val mockClient = mock[SocketClient] 
    mockFactory.expects("Some Socket Name").returning(mockClient) 
    (mockClient.frobnicate _).expects() 
    val scanner = new XScanner("path/to/config", mockFactory) 
    } 
} 
+0

これは、SocketClientが1つの引数を取るという事実をどのように克服するのかよく分かりません。私は書くことができません。 ヴァルmockClient =モック[SocketClient] mockFactory.expects( "いくつかのソケット名を")を返す(mockClientを) を模擬[SocketClient]コンパイルされませんので。あなたは引数を取らないようにSocketClientを変更することを提案していますか、またはすべての引数のデフォルト値を持っていますか?たとえデフォルトが意味を成さないとしても。 btwに返信いただきありがとうございます。 – jangoolie

+1

ああ、申し訳ありません - 私はそのシワを初めて見逃しました。今のところ、ScalaMock3は、特性と無argsクラスのみをモックできます。しかし、SocketClientを制御している場合でも、メソッドを定義し、それをクラスに実装するための特性を作成することができます。trait SocketClientBase;クラスSocketClient(...)は、SocketClientBaseを拡張します。それで、あなたはSocketClientBaseをモックすることができます。または私は何かを逃していますか? –

+0

また、私はあなたのコードを正確にコピーしても、コンパイルすることはできません。私は: メソッドをオーバーライドしているtraitスイートのSuiteMixinをオーバーライドする=> scala.collection.immutable.IndexedSeq [org.scalatest.Suite]; [エラー]メソッドNestedSuites in traitタイプのリスト=>リスト[org.scalatest.Suite]に互換性のないタイプがあります [エラー]クラスScannerTestがFunSuiteをMockFactoryで拡張しました{ – jangoolie

関連する問題