【问题标题】:Mocking overloaded method模拟重载方法
【发布时间】:2013-05-31 20:23:54
【问题描述】:

我正在使用 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 中做到这一点?也许使用另一个库?

【问题讨论】:

    标签: unit-testing scala mocking scala-2.10


    【解决方案1】:

    我相信您看到的编译器错误与 scalamock 无法正确模拟 PrintStream 类有关。如果查看 scalamock scaladocs 你会看到声明:

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

    由于PrintStream 类既不是接口也没有默认构造函数,我的猜测是 scalamock 无法正确模拟它,而您看到的错误是它的副作用。如果您将代码更改为使用 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 相同的限制。您可以阅读有关将 Mockito 与 Specs2 一起使用的更多信息here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-06
      • 2017-06-29
      • 2022-11-30
      • 1970-01-01
      • 2018-07-17
      相关资源
      最近更新 更多