2013-05-02 30 views
6

Tôi chạy vào một vấn đề trong khi viết một khớp tùy chỉnh cho NodeSeq:ScalaTest - văn bản tùy chỉnh quẹt

private def matchXML(expected: NodeSeq) = new Matcher[NodeSeq] { 
    def apply(left: NodeSeq): MatchResult = MatchResult(left xml_== expected, 
    "XML structure was not the same (watch spaces in tag texts)", 
    "XML messages were equal") 
} 

này biên dịch, nhưng đoạn mã sau:

val expected : NodeSeq = ... 
val xml : NodeSeq = ... 
xml should matchXML(expected) 

nguyên nhân:

error: overloaded method value should with alternatives: 
(beWord: XMLStripDecoratorTests.this.BeWord)XMLStripDecoratorTests.this.ResultOfBeWordForAnyRef[scala.collection.GenSeq[scala.xml.Node]] <and> 
(notWord: XMLStripDecoratorTests.this.NotWord)XMLStripDecoratorTests.this.ResultOfNotWordForAnyRef[scala.collection.GenSeq[scala.xml.Node]] <and> 
(haveWord: XMLStripDecoratorTests.this.HaveWord)XMLStripDecoratorTests.this.ResultOfHaveWordForSeq[scala.xml.Node] <and> 
(rightMatcher: org.scalatest.matchers.Matcher[scala.collection.GenSeq[scala.xml.Node]])Unit 
cannot be applied to (org.scalatest.matchers.Matcher[scala.xml.NodeSeq]) 
xml should (matchXML(expected)) 

Bất kỳ ý tưởng nào có ý nghĩa gì?

+0

định nghĩa của NodeSeq là gì? –

+0

@ MikaëlMayer Tôi cho rằng 'scala.xml.NodeSeq' – gzm0

Trả lời

7

Tại sao điều này không typecheck:

Các loại công trình kiểm tra theo cách sau.

xml.should(matchXML(expected)) 
  • Bởi vì phương pháp should không phải là một phần của một NodeSeq, trình biên dịch cố gắng tìm một implicit conversion cho xml đến một ShouldMatcher. Cuốn sách "Lập trình trong Scala" xác định rằng chuyển đổi ngầm như vậy nên là cụ thể nhất:

"Up qua Scala 2.7, đó là kết thúc của câu chuyện Bất cứ khi nào nhiều chuyển đổi tiềm ẩn áp dụng, trình biên dịch. từ chối lựa chọn giữa chúng. ... Scala 2.8 nới lỏng quy tắc này.Nếu một trong các chuyển đổi có sẵn có đặc điểm cụ thể hơn các trình chuyển đổi khác, thì trình biên dịch sẽ chọn trình biên dịch cụ thể hơn ... một chuyển đổi ẩn là cụ thể hơn một trường hợp khác nếu một trong các điều sau đây áp dụng: Loại đối số của kiểu cũ là ubtype của người thứ hai. .."

  • NodeSeq kéo dài Seq[Node], hàm sau do đó

    convertToSeqShouldWrapper[T](o : scala.GenSeq[T]) : SeqShouldWrapper[T]

    là cụ thể nhất một trong số tất cả những người khác.

Chương trình được viết lại như:

`convertToSeqShouldWrapper(xml).should(matchXML(expected))` 

nơi convertToSeqShouldWrapper(xml)SeqShouldWrapper[T] nơi T = GenSeq[Node].

Phương thức should từ SeqShouldWrapper chấp nhận Matcher[T] là chức năng loại T => MatchResult. Do đó, nó chấp nhận một Matcher[GenSeq[Node]].

Bởi vì T xuất hiện ở bên trái mũi tên, đối sánh không phải là covariant trong T, nhưng có thể bị thay đổi.A NodeSeqGenSeq[Node], vì vậy, Matcher[GenSeq[Node]]Matcher[NodeSeq], không phải ngược lại. Điều này giải thích lỗi ở trên, trong đó phương pháp should không thể chấp nhận Matcher[NodeSeq] và yêu cầu Matcher[GenSeq[Node]].

2 Solutions

  • Replace All trường hợp của NodeSeq để GenSeq[Node] để loại phù hợp ở khắp mọi nơi.
  • Cách khác, bọc xml một cách rõ ràng với chức năng chuyển đổi.

    convertToAnyShouldWrapper(xml).should(matchXML(expected))

+0

Khi giải pháp thứ hai hoạt động, giải pháp thứ nhất (chuyển đổi mọi thứ thành 'Seq [Node]') vẫn hiển thị cùng một lỗi. – HRJ

+0

Tôi đã có thể giải quyết điều này bằng cách chuyển đổi mọi thứ thành 'GenSeq [Node]'. Tôi đang sử dụng 'scalatest 2.0 M5', do đó có lẽ sự khác biệt. – HRJ

+0

Thật vậy, với phiên bản này, chữ ký của phương thức convertToSeqShouldWrapper là 'GenSeq [T] => SeqShouldWrapper [T]'. Vì vậy, tôi cập nhật câu trả lời của tôi. –

-1

Điều này trông giống như phương pháp matchXML của bạn không nằm trong phạm vi.

+0

Tôi gặp lỗi tương tự ngay cả khi matchXML nằm trong phạm vi. –

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