Scala (Test)로 instanceof 검사를 수행하는 방법


100

ScalaTest를 Java 프로젝트에 통합하려고합니다. 모든 JUnit 테스트를 ScalaTests로 대체합니다. 어느 시점에서 Guice의 Injector가 올바른 유형을 주입하는지 확인하고 싶습니다. Java에서는 다음과 같은 테스트가 있습니다.

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);
    }
}

하지만 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)
        }
    }
}

instanceofDoor/ Window/ 의 구성원이 아니라고 불평합니다 Roof. instanceofScala에서 그런 식으로 사용할 수 없습니까 ?

답변:


114

Scala는 Java가 아닙니다. Scala에는 연산자가없는 instanceof대신라는 매개 변수 메서드가 isInstanceOf[Type]있습니다.

ScalaTest Crash Course를 시청할 수도 있습니다 .


6
글쎄, 그것은 실제로 질문에 대한 답이 아닙니다. ScalaTest에는 유형 검사에 대한 기본 지원이 있습니다. 마틴-g @로부터 답변을 참조하십시오
maasg

"유형"이 특성 인 경우 어떻게합니까?
Lobo

올바르게 이해하는지 확실하지 않지만 동일해야합니다 isInstanceOf[TraitName]..
agilesteel

88

Scalatest 2.2.x (아마도 이전 버전 일 수도 있음)에서는 다음을 사용할 수 있습니다.

anInstance mustBe a[SomeClass]

4
이것은 ScalaTests의 최신 버전에서 권장되는 접근 방식입니다
maasg

6
또한 가능 a[Type]하면 문법적으로 정확 수)
사무엘

나는 그것을 찾고 있었다! :)
Atais 2017

22
tiger shouldBe a [Tiger]현재 구문입니다. scalatest.org/at_a_glance/FlatSpec
jhegedus

2
FreeSpec mustBe에 대해 원하는 doc.scalatest.org/3.0.1/#org.scalatest.MustMatchers 를 사용 하는 경우 @jhegedus 도 정확합니다 .
Tobi

30

JUnit-esque를 줄이고 싶고 ScalaTest의 매처를 사용하려면 유형 (막대 유형 삭제)과 일치하는 고유 한 속성 매처를 작성할 수 있습니다.

이 스레드가 매우 유용하다는 것을 알았습니다. http://groups.google.com/group/scalatest-users/browse_thread/thread/52b75133a5c70786/1440504527566dea?#1440504527566dea

그런 다음 다음과 같은 어설 션을 작성할 수 있습니다.

house.door should be (anInstanceOf[WoodenDoor])

대신에

assert(house.door instanceof WoodenDoor)

+1 매우 멋져 보이고 프로그래밍을하지 않는 사람들도 이해할 수 있습니다 (인스턴스가 무엇인지 안다고 가정하면 :-)).
helpermethod dec

구문 설탕이 당신이 추구하는 것이라면, 약간의 리팩토링을 통해 house.door는 (madeOf [Wood]) 또는 house.door는 (madeOf [Bamboo])로 작성할 수 있습니다.
Guillaume Belrose 2011


16

isInstanceOf [Type] 및 junit 조언에 대한 현재 답변은 좋지만 한 가지 추가하고 싶습니다 (이 페이지에 비 Junit 관련 용량으로 도착한 사람들을 위해). 대부분의 경우 스칼라 패턴 일치는 사용자의 요구에 적합합니다. 이 경우 무료로 형변환을 제공하고 오류의 여지가 적기 때문에 이러한 경우에 권장합니다.

예:

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

ScalaTest에서 패턴 일치를 테스트하는 권장 방법 inside(foo)은`foo match '대신 사용하는 것입니다. scalatest.org/user_guide/using_matchers#matchingAPattern
Rich Dougherty를

3

Guillaume의 ScalaTest 토론 참조 (및 James Moore가 연결 한 또 다른 토론)를 ScalaTest 2.x 및 Scala 2.10 (매니페스트 대신 ClassTag 사용)에 대해 업데이트 된 두 가지 방법으로 통합 :

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

2.11.8을 사용하여 컬렉션에 대한 주장을 수행합니다. 최신 구문은 다음과 같습니다.

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

3
삭제로 인해 Map의 유형 매개 변수를 확인할 수 없습니다 . 당신이 쓴 것은 쓰기와 동일합니다 scores shouldBe a[Map[_, _]]. 이것은 여기에 언급되어 있습니다 : scalatest.org/user_guide/using_matchers#checkingAnObjectsClass
Rich Dougherty
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.