2016-08-29 3 views
0

Ich bin schwer zu verstehen, warum implizite Importe nicht so funktionieren, wie ich sie in scalatest erwarte. Das vereinfachte Fehler Beispiel (unter Verwendung von Funken, aber ich kann es mit meiner benutzerdefinierten Klasse machen scheitert auch) ist wie folgt:Importieren impliziter Methoden in scalatest

class FailingSpec extends FlatSpec with Matchers with MySparkContext { 

    val testSqlctx = sqlctx 
    import sqlctx.implicits._ 

    "sql context implicts" should "work" in { 
     val failingDf = Seq(ID(1)).toDS.toDF 
    } 
} 

Das MySparkContext Merkmal schafft und zerstört Kontext Funken in beforeAll und afterAll und macht sqlctx verfügbar (bereits Um es implicits zu importieren ist es ein Puzzle, aber vielleicht für eine andere Zeit). Die .toDS und .toDF sind dann implizite Methoden importiert aus sqlctx.implicits. Ausführen der Testergebnisse in einem java.lang.NullPointerException.

Wenn ich den Import in Testblock Dinge bewegen arbeiten:

class WorkingSpec extends FlatSpec with Matchers with MySparkContext { 

    "sql context implicts" should "work" in {  
     val testSqlctx = sqlctx 
     import sqlctx.implicits._ 

     val workingDf = Seq(ID(1)).toDS.toDF 
    } 
} 

Irgendwelche Ideen, warum kann ich nicht implicits auf der obersten Ebene der Testklasse importieren?

Antwort

1

beforeAll vor allen Tests ausgeführt, aber nicht vor dem Konstruktor für die Klasse ausgeführt. Die Reihenfolge der Operationen in dem ersten Schnipsel ist:

  1. Konstruktor aufgerufen, Ausführung val testSqlctx = sqlctx und import sqlctx.implicits._

  2. beforeAll

    aufgerufen
  3. Tests

Und die Reihenfolge der Operationen ausführen für das zweite Snippet:

  1. beforeAll aufgerufen

  2. Tests laufen, val testSqlctx = sqlctx und import sqlctx.implicits._ Ausführung

Sie geben Ihre SparkContext einen Standard (null) Wert und initialisieren es in beforeAll, der erste Auftrag von Operationen Unter der Annahme, würde Versuchen Sie sqlctx zu verwenden, wenn es immernoch null ist, was die Nullzeigerausnahme verursacht.

+0

Danke, so offensichtlich im Nachhinein! Ich denke also, ich sollte die Dinge im Konstruktor des Merkmals richtig initialisieren und nicht in der Methode 'BeforeAll'. – psarka