IT-Swarm.Net

Cách thực hiện kiểm tra cá thể với Scala (Kiểm tra)

Tôi đang cố gắng kết hợp ScalaTest vào dự án Java của mình; thay thế tất cả các bài kiểm tra JUnit bằng ScalaTests. Tại một thời điểm, tôi muốn kiểm tra xem Guice's Injection có đúng loại không. Trong Java, tôi có một bài kiểm tra như thế này:

public class InjectorBehaviour {
    @Test
    public void shouldInjectCorrectTypes() {
        Injector injector = Guice.createInjector(new ModuleImpl());
        House house = injector.getInstance(House.class);

        assertTrue(house.door() instanceof WoodenDoor);
        assertTrue(house.window() instanceof BambooWindow);
        assertTrue(house.roof() instanceof SlateRoof);
    }
}

Nhưng tôi có một vấn đề khi làm tương tự với ScalaTest:

class InjectorSpec extends Spec {
    describe("An injector") {
        it("should inject the correct types") {
            val injector = Guice.createInjector(new ModuleImpl)
            val house = injector.getInstance(classOf[House])

            assert(house.door instanceof WoodenDoor)
            assert(house.window instanceof BambooWindow)
            assert(house.roof instanceof SlateRoof)
        }
    }
}

Nó phàn nàn rằng giá trị instanceof không phải là thành viên của Door/Window/Roof. Tôi không thể sử dụng instanceof theo cách đó trong Scala? 

77
helpermethod

Scala không phải là Java. Scala chỉ không có toán tử instanceof thay vào đó nó có một phương thức tham số gọi là isInstanceOf[Type].

Bạn cũng có thể thích xem ScalaTest Crash Course .

108
agilesteel

Với Scalatest 2.2.x (thậm chí sớm hơn), bạn có thể sử dụng:

anInstance mustBe a[SomeClass]
58
martin-g

Nếu bạn muốn ít JUnit-esque hơn và nếu bạn muốn sử dụng các công cụ đối sánh của ScalaTest, bạn có thể viết công cụ đối sánh thuộc tính của riêng bạn phù hợp với loại (loại thanh xóa).

Tôi thấy chủ đề này khá hữu ích: http://groups.google.com/group/scalatest-users/browse_thread/thread/52b75133a5c70786/1440504527566dea?#1440504527566dea

Sau đó, bạn có thể viết các xác nhận như:

house.door should be (anInstanceOf[WoodenDoor])

thay vì 

assert(house.door instanceof WoodenDoor)
29
Guillaume Belrose

Các câu trả lời hiện tại về isInstanceOf [Loại] và lời khuyên của Junit là tốt nhưng tôi muốn thêm một điều (đối với những người đã vào trang này trong khả năng không liên quan đến Junit). Trong nhiều trường hợp phù hợp với mô hình scala sẽ phù hợp với nhu cầu của bạn. Tôi muốn giới thiệu nó trong những trường hợp đó vì nó cung cấp cho bạn kiểu chữ miễn phí và ít lỗi hơn.

Thí dụ:

OuterType foo = blah
foo match {
  case subFoo : SubType => {
    subFoo.thingSubTypeDoes // no need to cast, use match variable
  }
  case subFoo => {
    // fallthrough code
  }
}
15
alexbobp

Hợp nhất tài liệu tham khảo thảo luận ScalaTest của Guillaume (và một cuộc thảo luận khác được liên kết bởi James Moore) thành hai phương pháp, được cập nhật cho ScalaTest 2.x và Scala 2.10 (để sử dụng ClassTag thay vì bảng kê khai):

import org.scalatest.matchers._
import scala.reflect._

def ofType[T:ClassTag] = BeMatcher { obj: Any =>
  val cls = classTag[T].runtimeClass
  MatchResult(
    obj.getClass == cls,
    obj.toString + " was not an instance of " + cls.toString,
    obj.toString + " was an instance of " + cls.toString
  )
}

def anInstanceOf[T:ClassTag] = BeMatcher { obj: Any =>
  val cls = classTag[T].runtimeClass
  MatchResult(
    cls.isAssignableFrom(obj.getClass),
    obj.getClass.toString + " was not assignable from " + cls.toString,
    obj.getClass.toString + " was assignable from " + cls.toString
  )
}
2
Raman

Tôi sử dụng 2.11.8 để thực hiện xác nhận với các bộ sưu tập. Cú pháp mới hơn như sau:

val scores: Map[String, Int] = Map("Alice" -> 10, "Bob" -> 3, "Cindy" -> 8)
scores shouldBe a[Map[_, _]] 
0
aristotll