web-dev-qa-db-de.com

So führen Sie eine Überprüfung mit Scala durch (Test)

Ich versuche, ScalaTest in mein Java-Projekt zu integrieren. Ersetzen aller JUnit-Tests durch ScalaTests. An einem Punkt möchte ich prüfen, ob Guice's Injector den richtigen Typ einspritzt. In Java habe ich so einen Test:

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

Aber ich habe ein Problem damit, das gleiche mit ScalaTest zu machen:

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

Es beschwert sich, dass der Wert instanceof kein Mitglied von Door/Window/Roof ist. Kann ich instanceof in Scala nicht auf diese Weise verwenden? 

77
helpermethod

Scala ist kein Java. Scala hat einfach nicht den Operator instanceof, sondern eine parametrische Methode namens isInstanceOf[Type].

Sie können auch einen ScalaTest Crash-Kurs genießen.

108
agilesteel

Mit Scalatest 2.2.x (vielleicht sogar früher) können Sie Folgendes verwenden:

anInstance mustBe a[SomeClass]
58
martin-g

Wenn Sie weniger JUnit-esque sein möchten und ScalaTests Matchers verwenden möchten, können Sie einen eigenen Eigenschafts-Matcher schreiben, der für den Typ (Streichertyp) gilt.

Ich fand diesen Thread sehr nützlich: http://groups.google.com/group/scalatest-users/browse_thread/thread/52b75133a5c70786/1440504527566dea?#1440504527566dea

Sie können dann Assertionen schreiben wie:

house.door should be (anInstanceOf[WoodenDoor])

anstatt 

assert(house.door instanceof WoodenDoor)
29

Die aktuellen Antworten zu isInstanceOf [Type] und den Junit-Ratschlägen sind gut, aber ich möchte eine Sache hinzufügen (für Personen, die diese Seite in einer nicht mit Junit zusammenhängenden Funktion besucht haben). In vielen Fällen passt sich das Scala-Muster an Ihre Bedürfnisse an. Ich würde es in diesen Fällen empfehlen, weil es Ihnen die Typumwandlung kostenlos gibt und weniger Platz für Fehler lässt.

Beispiel:

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

Konsolidierung der ScillaTest-Diskussionsreferenz von Guillaume (und einer weiteren von James Moore verknüpften Diskussion) in zwei für ScalaTest 2.x und Scala 2.10 aktualisierte Methoden (um ClassTag statt Manifest zu verwenden):

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

Ich verwende 2.11.8, um die Assertion mit Sammlungen durchzuführen. Die neuere Syntax lautet wie folgt:

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