web-dev-qa-db-fra.com

Comment faire une instance de vérification avec Scala (Test)

J'essaie d'intégrer ScalaTest dans mon projet Java. en remplaçant tous les tests JUnit par ScalaTests. À un moment donné, je veux vérifier si l'injecteur de Guice injecte le type correct. En Java, j'ai un test comme celui-ci:

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

Mais j'ai un problème avec 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)
        }
    }
}

Il se plaint que la valeur instanceof ne soit pas membre de Door/Window/Roof. Je ne peux pas utiliser instanceof de cette façon en Scala? 

77
helpermethod

Scala n'est pas Java. Scala n'a tout simplement pas l'opérateur instanceof mais une méthode paramétrique appelée isInstanceOf[Type].

Vous pourriez également aimer regarder un cours intensif de ScalaTest .

108
agilesteel

Avec Scalatest 2.2.x (peut-être même plus tôt), vous pouvez utiliser:

anInstance mustBe a[SomeClass]
58
martin-g

Si vous voulez avoir moins de JUnit-esque et si vous voulez utiliser les correspondants de ScalaTest, vous pouvez écrire votre propre matcher de propriété qui correspond au type (effacement du type de barre).

J'ai trouvé ce fil très utile: http://groups.google.com/group/scalatest-users/browse_thread/thread/52b75133a5c70786/1440504527566dea?#1440504527566dea

Vous pouvez ensuite écrire des assertions telles que:

house.door should be (anInstanceOf[WoodenDoor])

au lieu de 

assert(house.door instanceof WoodenDoor)
29
Guillaume Belrose

Les réponses actuelles sur isInstanceOf [Type] et les conseils Junit sont bonnes, mais je souhaite ajouter une chose (pour les personnes ayant consulté cette page sans aucune relation avec Junit). Dans de nombreux cas, la correspondance des motifs scala répondra à vos besoins. Je le recommanderais dans ces cas-là, car cela vous donne la conversion de typographie gratuitement et laisse moins de place à l'erreur.

Exemple:

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

Consolidation de la référence de discussion ScalaTest de Guillaume (et une autre discussion liée par James Moore) en deux méthodes, mises à jour pour ScalaTest 2.x et Scala 2.10 (pour utiliser ClassTag plutôt que manifeste):

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

J'utilise 2.11.8 pour faire l'assertion avec des collections. La syntaxe la plus récente est la suivante:

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