8

オーバーロードされたメソッドを含むクラスをモックするためにscalamockを使用していますが、いくつかのエラーが発生しています。

例えば:

val out = mock[PrintStream]

(out.print _).expects("cmd \r\n")

次のエラーが発生します。

[error] [...]/src/test/scala/chili.scala:19: ambiguous reference to overloaded definition,
[error] both method print in class PrintStream of type (x$1: String)Unit
[error] and  method print in class PrintStream of type (x$1: Array[Char])Unit

しかし、私が使用しようとすると:

(out.print(_: String)).expects("cmd \r\n")

エラーも表示されます:

[info] [...]/src/test/scala/chili.scala:19: Unable to resolve overloaded method print
[info]       (out.print(_: String)).expects("cmd \r\n")
[info]                 ^
[error] [...]/src/test/scala/chili.scala:19: value expects is not a member of String => Unit
[error]       (out.print(_: String)).expects("cmd \r\n")

scalaでこれを行う方法はありますか? 多分別のライブラリを使用していますか?

4

1 に答える 1

16

表示されているコンパイラ エラーは、scalamock がPrintStreamクラスを適切にモックできないという事実に関係していると思います。scalamock のscaladocsを見ると、次のステートメントが表示されます。

At present, ScalaMock can only mock traits, Java interfaces, and non-final 
classes that define a default constructor

クラスはインターフェースでもデフォルトのコンストラクターでもないためPrintStream、scalamock は適切にモックできず、表示されているエラーはその副作用であると推測されます。代わりにa を使用するようにコードを変更した場合OutputStream(これはインターフェイスであるため、scalamock の制限に適合します)、オーバーロードされたメソッドのモックを次のように実行できます。

val mockStream = mock[OutputStream]      
(mockStream.write(_:Int)) expects(1)
(mockStream.write(_:Array[Byte])) expects(Array[Byte](1,2,3))

個人的には、この種の制限がないため、Specs2 内で使用される Mockitoを好みます。PrintWriterクラスを使用し、Mockito でモックを使用してそのクラスのテスト仕様を作成する例は次のとおりです。

import java.io.PrintStream
import java.io.File
import org.specs2.mutable.Specification
import org.specs2.mock.Mockito

class MockitoExample extends Specification with Mockito{
  val mockPrinter = mock[PrintStream]
  val myPrinter = new MyPrintingClass{
    override val printer = mockPrinter
  }

  "A request to print and attay of strings" should{
    "call println on the PrintStream for each string supplied" in {
      myPrinter print Array("foo", "bar")
      there was one(mockPrinter).println("foo")
      there was one(mockPrinter).println("bar")
    }
  }
}

class MyPrintingClass{
  val printer = new PrintStream(new File("foo.txt"))

  def print(strings:Array[String]) = strings foreach (printer.println(_))
}

これは非常に単純な例であり、テスト前のスタブを使用せずにテスト後の検証のみを使用しています (戻り値の型printlnがあるためUnit) が、少なくとも Mockito が scalamock と同じ制限を受けていないことがわかります。Specs2 で Mockito を使用する方法の詳細については、こちらを参照してください。

于 2013-06-03T12:43:15.070 に答える