Ausgabe
Ich möchte Code, der DataFrame aus RDBMS liest, mithilfe von sparkSession.read.jdbc(...)
. Aber ich habe keine Möglichkeit gefunden, DataFrameReader zu verspotten, um Dummy-DataFrame zum Testen zurückzugeben.
Codebeispiel:
object ConfigurationLoader {
def readTable(tableName: String)(implicit spark: SparkSession): DataFrame = {
spark.read
.format("jdbc")
.option("url", s"$postgresUrl/$postgresDatabase")
.option("dbtable", tableName)
.option("user", postgresUsername)
.option("password", postgresPassword)
.option("driver", postgresDriver)
.load()
}
def loadUsingFilter(dummyFilter: String*)(implicit spark: SparkSession): DataFrame = {
readTable(postgresFilesTableName)
.where(col("column").isin(fileTypes: _*))
}
}
Und das zweite Problem – um das Scala-Objekt zu verspotten, sieht so aus, als müsste ich einen anderen Ansatz verwenden, um einen solchen Dienst zu erstellen.
Lösung
Unit-Tests sind meiner Meinung nach nicht dazu gedacht, Datenbankverbindungen zu testen. Dies sollte in Integrationstests durchgeführt werden, um zu überprüfen, ob alle Teile zusammenarbeiten. Komponententests sollen nur Ihre Funktionslogik testen und nicht die Fähigkeit von Spark, aus einer Datenbank zu lesen.
Aus diesem Grund würde ich Ihren Code etwas anders gestalten und genau das tun, ohne mich um die DB zu kümmern.
/** This, I don't test. I trust spark.read */
def readTable(tableName: String)(implicit spark: SparkSession): DataFrame = {
spark.read
.option(...)
...
.load()
// Nothing more
}
/** This I test, this is my logic. */
def transform(df : DataFrame, dummyFilter: String*): DataFrame = {
df
.where(col("column").isin(fileTypes: _*))
}
Dann verwende ich den Code auf diese Weise in der Produktion.
val source = readTable("...")
val result = transform(source, filter)
Und nun transform
, das enthält meine Logik, ist einfach zu testen. Falls Sie sich fragen, wie man Dummy-Datenrahmen erstellt, mag ich Folgendes:
val df = Seq((1, Some("a"), true), (2, Some("b"), false),
(3, None, true)).toDF("x", "y", "z")
// and the test
val result = transform(df, filter)
result should be ...
Beantwortet von – Oli
Antwort geprüft von – David Goodson (FixError Volunteer)