it-swarm-pt.tech

Como fazer um exemplo de verificação com Scala (teste)

Estou tentando incorporar o ScalaTest ao meu projeto Java; substituindo todos os testes JUnit por ScalaTests. Em um ponto, quero verificar se o injetor de Guice injeta o tipo correto. Em Java, eu tenho um teste assim:

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

Mas eu tenho um problema em fazer o mesmo com o 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)
        }
    }
}

Ele reclama que o valor instanceof não é um membro de Door/Window/Roof. Não posso usar instanceof dessa maneira no Scala? 

77
helpermethod

Scala não é Java. O Scala simplesmente não tem o operador instanceof em vez disso, ele tem um método paramétrico chamado isInstanceOf[Type].

Você também pode assistir a um ScalaTest Crash Course .

108
agilesteel

Com o Scalatest 2.2.x (talvez até mais antigo), você pode usar:

anInstance mustBe a[SomeClass]
58
martin-g

Se você quer ser menos JUnit-esque e se você quiser usar os matchers do ScalaTest, você pode escrever o seu próprio matcher de propriedades que combine com o tipo (eliminação do tipo de barra).

Achei este tópico bastante útil: http://groups.google.com/group/scalatest-users/browse_thread/thread/52b75133a5c70786/1440504527566dea?#1440504527566dea

Você pode então escrever asserções como:

house.door should be (anInstanceOf[WoodenDoor])

ao invés de 

assert(house.door instanceof WoodenDoor)
29
Guillaume Belrose

As respostas atuais sobre isInstanceOf [Type] e junit advice são boas, mas eu quero adicionar uma coisa (para pessoas que chegaram a esta página em uma capacidade não relacionada a junções). Em muitos casos, a correspondência de padrões scala atenderá às suas necessidades. Eu recomendaria isso nesses casos, pois dá a você a typecasting de graça e deixa menos espaço para erros.

Exemplo:

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

Consolidando a referência de discussão ScalaTest de Guillaume (e outra discussão ligada por James Moore) em dois métodos, atualizados para ScalaTest 2.xe Scala 2.10 (para usar ClassTag em vez de manifesto):

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

Eu uso 2.11.8 para fazer a afirmação com coleções. A sintaxe mais recente é a seguinte:

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