unit testing - Mocking método sobrecargado
unit-testing scala (1)
Creo que los errores del compilador que está viendo tienen que ver con el hecho de que scalamock no puede burlarse de la clase PrintStream
. Si miras Scalamock Scaladocs verás la siguiente declaración:
At present, ScalaMock can only mock traits, Java interfaces, and non-final
classes that define a default constructor
Como la clase PrintStream
no es ni una interfaz ni tiene un constructor predeterminado, supongo que scalamock no puede burlarse de él y los errores que está viendo son un efecto secundario de eso. Si cambiaste tu código para usar un OutputStream
lugar (que es una interfaz y por lo tanto cumple con las restricciones de scalamock), podrías hacer tu burla de método sobrecargado de esta manera:
val mockStream = mock[OutputStream]
(mockStream.write(_:Int)) expects(1)
(mockStream.write(_:Array[Byte])) expects(Array[Byte](1,2,3))
Personalmente, prefiero Mockito utilizado dentro de Specs2 ya que no tiene este tipo de restricciones. Un ejemplo de una clase que usa PrintWriter
y luego una especificación de prueba para esa clase usando burla con Mockito es la siguiente:
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(_))
}
Ahora bien, este es un ejemplo muy trivial, que utiliza solo verificaciones posteriores a la prueba sin cortes previos a la prueba (porque println
tiene un tipo de devolución de Unit
), pero al menos se puede ver que Mockito no sufre las mismas restricciones que scalamock. Puede leer más sobre el uso de Mockito con Specs2 aquí .
Estoy usando scalamock para burlarme de una clase que contiene algunos métodos sobrecargados, pero estoy recibiendo algunos errores.
Por ejemplo:
val out = mock[PrintStream]
(out.print _).expects("cmd /r/n")
Genera el siguiente error:
[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
Pero si trato de usar:
(out.print(_: String)).expects("cmd /r/n")
También recibo un error:
[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")
¿Hay alguna manera de hacer esto en Scala? Tal vez usando otra biblioteca?