如何模拟Spark SqlContext的方法?

She*_*har 0 unit-testing scala apache-spark spark-dataframe

我正在使用Scala编写一个Spark应用程序,我正在尝试为一个方法编写单元测试,该方法将从Hive表加载数据,对其进行一些处理并将结果作为数据帧返回.

方法如下所示:

private def filterData(SqlContext context, tableName): DataFrame = {
  val table = context.table(tableName)
  val selectColumnList = Seq("colA", "colB")
  table.select(selectColumnList).filter(table.col("colC") > 100)
}
Run Code Online (Sandbox Code Playgroud)

我想知道如何模拟SqlContext.table()方法,以便我可以在调用时提供一些测试数据,或者是否有其他方法可以使用Scala实现它?

Kra*_*log 5

不要嘲笑你不拥有的东西.

当您这样做时,您假设您知道代码的行为方式,因此您可以提供在测试中调用该代码的结果.这种假设可能会在你面前爆炸,特别是当你升级库版本时 - 测试通过,生产中断.

相反,为它编写一个适配器,然后在测试使用它的单元时使用它的模拟实例.适配器将您的代码与外部世界分开.要测试适配器本身,您必须编写一个集成测试,它会旋转spark(或适配器的任何实现)并检查适配器是否正常工作.

在此输入图像描述

因此,您的适配器可能包含您上面描述的功能,您需要编写一个集成测试来检查真正的Spark.但是,当您使用适配器时,您可以模拟它.

trait DataProcessor {
    def filterData(SqlContext context, tableName): DataFrame
}

class SparkDataProcessor extends DataProcessor {
    override def filterData(SqlContext context, tableName): DataFrame = {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

并且使用它的类的测试:

class MyThingieTest extends Spec {
    "should use the data processor" >> {
        val mockDataProcessor = mock[DataProcessor]
        mockDataProcessor.filterData(context, tableName) returns ...

        MyThingie(mockDataProcessor).doSomething must beEqualTo(...)
    }
}
Run Code Online (Sandbox Code Playgroud)

这样您就可以指定适配器返回的内容.注意 - 确保不会泄漏适配器API中的第三方实现.它应该只返回您的数据结构.

是另一篇关于这个主题的伟大文章.