2010-08-26 5 views
9

Tôi đang sử dụng mockito và cố gắng giả lập một đối tượng scala.Mocking scala object

object Sample { } 
//test 
class SomeTest extends Specification with ScalaTest with Mockito { 
    "mocking should succeed" in { 
     val mockedSample = mock[Sample] 
    } 
} 

Điều này cho tôi hai lỗi biên dịch.

error: Not found type Sample 
error: could not find implicit value for parameter m: 
scala.reflect.ClassManifest[<error>] 

Nếu tôi thay đổi Mẫu từ đối tượng đến lớp, nó hoạt động. Có thể giả lập đối tượng scala bằng mockito không? Nếu có thì sao?

Trả lời

10

Khi được viết, Sample là một singleton thuần túy. Loại của nó là của riêng nó và chỉ có một thành viên của loại đó, thời gian. Scala object s có thể mở rộng một lớp khác (có thể trừu tượng, nếu nó cung cấp các định nghĩa cần thiết để làm cho nó một cách cụ thể) và các đặc điểm. Làm điều đó mang lại cho nó một loại nhận dạng bao gồm những tổ tiên đó.

Tôi không biết Mockito đang thực sự làm gì, nhưng theo ý tôi, những gì bạn đang yêu cầu hoàn toàn trái ngược với những gì Scala object là.

+3

Chắc chắn đồng ý ở đây. Bạn có thể thử giả lập [Sample.type], nhưng tôi nghi ngờ nó sẽ hoạt động trong thực tế. Tôi khuyên bạn nên có mẫu mở rộng một số đặc điểm giao diện và giả lập nó theo cách đó. Vấn đề lớn là nếu bạn muốn tiêm mô hình của bạn thay cho mẫu Singleton, bạn sẽ phải thực hiện một số phép thuật phản chiếu đẹp, ác, vui nhộn. Nếu bạn quan tâm, chúng tôi có thể đăng bài đó. – jsuereth

+0

Tôi đã xem mã nguồn Mockito ngày hôm sau để trả lời một câu hỏi liên quan (vì lý do nào đó tôi không thể tìm thấy, bây giờ) và dường như tôi nhớ lại một trong những máy phát "giả" chỉ trả về một giá trị cụ thể thay vì cố gắng để tạo ra các biến thể/biến thể. –

+0

Có cách nào để thực hiện điều này với Powermock hoặc tương tự không? Nếu tôi có một phương thức (hiệu quả toàn cầu) trên một đối tượng đồng hành, có vẻ như hợp lý khi muốn giả lập hành vi của nó; chắc chắn đây là một mô hình phổ biến trong thế giới ruby. – Korny

6

Hãy nhớ rằng bạn có thể giả các phương pháp của một object nếu bạn nhấc họ vào các chức năng.

case class Person(name: String) 
object Person { 
    def listToJson(lp: List[Person]) = "some actual implementation" 
} 

class ClassUnderTest(listToJson: (List[Person]) => String = Person.listToJson(_)) { 
    def testIt(lp: List[Person]) = listToJson(lp) 
} 

import org.specs._ 
import org.specs.mock.Mockito 
import org.mockito.Matchers._ 

class ASpec extends Specification with Mockito { 
    "a thing" should { 
    "do whatever" in { 
     val m = mock[(List[Person]) => String] 
     val subject = new ClassUnderTest(m) 
     m(Nil) returns "mocked!" 
     subject.testIt(Nil) must_== "mocked! (this will fail on purpose)" 
    } 
    } 
} 

Ở đây tôi không chế nhạo đối tượng Người, nhưng phương pháp trên đó (có thể là nơi OP đang có ý định).

Kết quả thử nghiệm cho thấy các chế nhạo hoạt động:

[info] == ASpec == 
[error] x a thing should 
[error] x do whatever 
[error]  'mocked![]' is not equal to 'mocked![ (this will fail on purpose)]' (ASpec.scala:21) 
[info] == ASpec == 

Trong khi đó, việc sử dụng sản xuất thời gian của ClassUnderTest chỉ đơn giản là new ClassUnderTest do chức năng tiêm là một đối số mặc định.

9

Gần đây, tôi đã phát hành ScalaMock, một thư viện nhạo báng cho Scala có thể, trong số những thứ khác, các đối tượng đơn lẻ và đồng hành giả.

+4

Trên trang được cung cấp, hỗ trợ cho các đối tượng singleton và đồng hành được khai báo trong phần có tiêu đề "Kế hoạch tương lai". Framework hiện có hỗ trợ các tính năng đó không? – Zotov

+2

@Zotov, có vẻ như sự hỗ trợ cho các đối tượng nhại chỉ có sẵn trong ScalaMock2 với việc sử dụng một plugin trình biên dịch 2.9, như được giải thích trong [hướng dẫn] này (http://paulbutcher.com/2011/11/06/scalamock- từng bước một/). ScalaMock3 không yêu cầu plugin trình biên dịch vì nó dựa trên Scala 2.10 macro thay vào đó, nhưng nó không hỗ trợ tất cả các tính năng của ScalaMock2, như đã đề cập trong [bài đăng trên blog] này (http://paulbutcher.com/2012/06/04/scalamock-3-0-preview-release /). Do đó, các đối tượng nhại là không được hỗ trợ trong 2.10): Theo như tôi có thể nói, điều đó vẫn có vẻ là trạng thái hiện tại của dự án. –

+0

Thư viện này vẫn không hoạt động tốt – danielrvt