2013-05-31 3 views
7

Ich benutze Scalamock, um eine Klasse zu verspotten, die einige überladene Methoden enthält, aber ich bekomme einige Fehler.Mocking überladen Methode

Zum Beispiel:

val out = mock[PrintStream] 

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

Löst den folgenden Fehler:

[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 

Aber wenn ich zu verwenden versuchen:

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

ich auch einen Fehler:

[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") 

Gibt es eine Möglichkeit, dies in Scala zu tun? Vielleicht mit einer anderen Bibliothek?

Antwort

10

Ich glaube, die Compilerfehler, die Sie sehen, haben mit der Tatsache zu tun, dass Scalamock die PrintStream Klasse nicht richtig nachmachen kann. Wenn Blick auf die scalamock scaladocs Sie die Anweisung sehen:

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

Als PrintStream Klasse weder eine Schnittstelle ist auch nicht Standardkonstruktor haben, meine Vermutung ist, dass scalamock nicht richtig es verspotten und die Fehler, die Sie sehen, sind sind ein Nebeneffekt davon. Wenn Sie Ihren Code geändert, anstatt eine OutputStream zu verwenden (was eine Schnittstelle und erfüllt damit scalamock die Einschränkungen), könnten Sie Ihre überladene Methode wie diese spöttischen tun:

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

Ich persönlich bevorzugen Mockito innerhalb Specs2 verwendet, wie es funktioniert nicht diese Art von Einschränkungen haben. Ein Beispiel für eine Klasse PrintWriter und anschließend für diese Klasse einer Testspezifikation mit Mockito mit spöttischen ist wie folgt:

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(_)) 
} 

Nun ist dies ein sehr einfaches Beispiel, nur post-Testprüfungen unter Verwendung ohne Vortest Stubbings (Weil println eine Unit Rückgabetyp hat), aber zumindest können Sie sehen, dass Mockito nicht unter den gleichen Einschränkungen wie Skalamock leidet. Sie können mehr über die Verwendung von Mockito mit Specs2 here lesen.

+0

Gute Antwort. Vielen Dank – simao