如何使用Scala进行instanceof检查(测试)

hel*_*hod 92 java junit scala scalatest

我正在尝试将ScalaTest合并到我的Java项目中; 用ScalaTests替换所有JUnit测试.有一次,我想检查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);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是我在使用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)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

它抱怨说,价值instanceof是不是成员Door/ Window/ Roof.我不能instanceof在Scala中使用这种方式吗?

agi*_*eel 112

Scala不是Java.Scala只是没有运算符,instanceof而是有一个名为的参数方法isInstanceOf[Type].

您可能还喜欢观看ScalaTest速成课程.

  • 我的答案差不多有5年了.那个'anInstance必须由@ martin-g显示的[SomeClass]`技术当时不存在(正如他所说的那样).如果你想对此有所了解,我的回答完全回答了OP的问题,即:"我不能在Scala中使用这种方法吗?".这两种方法都适用于今天,因此都是正确的答案.祝你有美好的一天. (9认同)
  • 好吧,那并没有真正回答这个问题.ScalaTest内置了对类型检查的支持.请参阅@ martin-g的答案 (3认同)

mar*_*n-g 74

使用Scalatest 2.2.x(甚至可能更早),您可以使用:

anInstance mustBe a[SomeClass]
Run Code Online (Sandbox Code Playgroud)

  • `tiger shouldBe a [Tiger]`是当前的语法http://www.scalatest.org/at_a_glance/FlatSpec (17认同)
  • 还有`a [Type]`所以你可以语法正确;) (6认同)
  • 这是ScalaTests最新版本的推荐方法 (4认同)
  • @jhegedus `mustBe` 也是正确的,如果你使用 http://doc.scalatest.org/3.0.1/#org.scalatest.MustMatchers 你想要的 FreeSpec。 (2认同)

Gui*_*ose 30

如果你想减少JUnit-esque,如果你想使用ScalaTest的匹配器,你可以编写自己的匹配类型(bar类型擦除)的属性匹配器.

我发现这个帖子非常有用:http://groups.google.com/group/scalatest-users/browse_thread/thread/52b75133a5c70786/1440504527566dea?#1440504527566dea

然后你可以编写如下的断言:

house.door should be (anInstanceOf[WoodenDoor])
Run Code Online (Sandbox Code Playgroud)

代替

assert(house.door instanceof WoodenDoor)
Run Code Online (Sandbox Code Playgroud)


小智 15

关于isInstanceOf [Type]和junit建议的当前答案是好的,但我想添加一件事(对于以非junit相关容量到达此页面的人).在许多情况下,scala模式匹配将满足您的需求.我会在这些情况下推荐它,因为它为您提供免费的类型转换,并留下更少的错误空间.

例:

OuterType foo = blah
foo match {
  case subFoo : SubType => {
    subFoo.thingSubTypeDoes // no need to cast, use match variable
  }
  case subFoo => {
    // fallthrough code
  }
}
Run Code Online (Sandbox Code Playgroud)