2012-06-11 15 views
7

Tôi mới sử dụng Scala (từ Java) và tôi muốn phát triển TDD/BDD. Vì vậy, trước khi biết nhiều về Scala, tôi đã đi sâu vào Scalatest.Scala - thiết lập kiểm tra đơn vị (sử dụng vòng loại điều chỉnh truy cập?)

Tôi tự hỏi bạn nghĩ gì về chiến lược truy cập tốt để kiểm tra đơn vị, từ quan điểm mà bạn muốn kiểm tra càng nhiều càng tốt.

Giả sử tôi có một thế giới lớp mà tôi muốn kiểm tra và một tác nhân hạng mà không nên biết mọi thứ về thế giới.

package program { 
    package world { 
    class World { 
     private var notForAgent 
     def forAgentDuringActing 
     // forAgentDuringActing has an important side effect in notForAgent 
    } 
    } 

    package agent { 
    class Agent 
    // would call World.forAgentDuringActing 
    } 

    package world.test { 
    class WorldSpec extends FunSpec { 
     describe("The world") { 
     it("should have side-effect behaviour when the agent acts on it") { 
      // ... the test ... 
     } 
     } 
    } 
    } 
} 

Lưu ý rằng các tuyên bố gói này không phải là thiêng liêng đối với tôi. Điều tôi thực sự muốn, đó là WorldSpec sẽ giống như một vật thể đồng hành với thế giới, để nó có thể kiểm tra tác dụng phụ.

Tôi nghĩ rằng các vòng loại công cụ sửa đổi truy cập có thể hữu ích. Tôi có thể nói private[world] notForAgent, nhưng đó thực sự là truy cập nhiều hơn tôi muốn. Những gì tôi thực sự muốn là một cái gì đó như private[this, test.WorldSpec] notForAgent, nhưng tôi không nghĩ rằng nhiều vòng loại được cho phép.

Bạn sẽ làm gì để thực hiện điều này? Ngoài ra, bạn có thể chỉ ra nơi suy nghĩ của tôi đi sai hướng?

p.s. Tôi biết tuyên bố "không bao giờ thử nghiệm tư nhân". Nhưng tôi cũng biết ý kiến ​​"Kiểm thử quan trọng hơn bản thân mã nguồn. Điều chỉnh truy cập thay đổi nếu nó cần thiết để thử nghiệm". Tuy nhiên, tôi muốn tránh thảo luận trong chủ đề này.

Trả lời

9

Nếu bạn đang hỏi "Cách thử nghiệm các phương thức riêng tư?", Thì ScalaTest thực sự hỗ trợ điều này. Xem here.

class C { 
    private def m(x: Int) = x 
} 

class CTests extends /*any test suite you like*/ with PrivateMethodTester { 
    val decoratedM = PrivateMethod[Int]('m) 
    val c = new C 
    val actual = c invokePrivate decoratedM(4711) 
    val expected = 4711 
    actual should be(expected) // this line depends on the test suite you've chosen 
} 
+0

Vâng, tôi biết điều đó. Tuy nhiên, trạng thái tôi muốn thử nghiệm là một var, không phải là một phương thức. Tuy nhiên, câu trả lời của bạn là thực sự có thể sử dụng, bởi vì dường như Scala cũng làm cho một phương pháp getter cho một val tư nhân. Vì vậy, bạn có thể làm các bài kiểm tra theo cách này. Sẽ không có cách nào để cho phép điều này theo cách tự nhiên hơn (chẳng hạn như trường hợp với đối tượng đồng hành)? – qkrijger

+0

Hmm, tôi không thể bỏ phiếu cho câu trả lời của bạn vì tôi chưa có 15 danh tiếng ... :( – qkrijger

+0

Bây giờ tôi đang thực hiện một số thử nghiệm trong thời trang này, tôi phải nói rằng không khí trở nên hơi có mùi. Đối với một điều, kiểm tra này phá vỡ sau khi một refactor (mà không phải là một vấn đề lớn, nhưng không sạch hoặc là) .Một người nào đó có ý tưởng về cách cải thiện các thiết lập, mà sẽ được tốt đẹp là tốt. Tôi thực sự thích ý tưởng của một đối tượng thử nghiệm đơn vị đồng hành, nhưng tôi sẽ không biết làm thế nào để đạt được một cái gì đó như thế (nếu có thể) – qkrijger