2013-05-31 29 views
7

Tôi đang sử dụng scalamock để giả lập một lớp có chứa một số phương thức quá tải nhưng tôi gặp phải một số lỗi.Phương pháp nạp chồng quá tải

Ví dụ:

val out = mock[PrintStream] 

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

Tăng các lỗi sau:

[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 

Nhưng nếu tôi cố gắng sử dụng:

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

Tôi cũng nhận được một lỗi:

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

Có cách nào để làm điều này trong scala? Có thể sử dụng thư viện khác?

Trả lời

10

Tôi tin rằng các lỗi trình biên dịch bạn đang thấy phải làm với thực tế là scalamock có thể không đúng cách chế nhạo lớp PrintStream. Nếu nhìn vào scalamock scaladocs bạn sẽ thấy những tuyên bố:

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

Như lớp PrintStream không phải là một giao diện cũng không có constructor mặc định, tôi đoán là scalamock thể không đúng cách châm biếm nó và các lỗi bạn đang nhìn thấy là một tác dụng phụ của điều đó. Nếu bạn đã thay đổi mã của bạn để sử dụng một OutputStream thay vì (đó là một giao diện và do đó đáp ứng hạn chế scalamock của), bạn có thể làm phương pháp quá tải của bạn chế giễu như thế này:

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

Cá nhân, tôi thích Mockito sử dụng trong vòng Specs2 như nó không có các loại hạn chế này. Một ví dụ về một lớp học sử dụng PrintWriter và sau đó một spec thử nghiệm cho lớp rằng việc sử dụng chế giễu với Mockito là như sau:

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

Bây giờ đây là một ví dụ rất tầm thường, chỉ sử dụng xác minh sau khi xét nghiệm không có stubbings pre-test (vì println có loại trả về Unit), nhưng ít nhất bạn có thể thấy rằng Mockito không bị hạn chế giống như scalamock. Bạn có thể đọc thêm về cách sử dụng Mockito với Specs2 here.

+0

Câu trả lời hay. Cảm ơn – simao

Các vấn đề liên quan