如何模拟 Spark SqlContext 的方法?
How to mock methods of Spark SqlContext?
我正在使用 Scala 编写一个 Spark 应用程序,我正在尝试为一种将从 Hive table 加载数据的方法编写单元测试,对其进行一些处理并 return 结果为一个数据框。
方法如下图所示:
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)
}
我想知道如何模拟 SqlContext.table()
方法,以便我可以在调用它时提供一些测试数据,或者是否有任何其他方法可以使用 Scala 实现它?
不要嘲笑你没有的东西。
当您这样做时,您假设您知道该代码的行为方式,因此您可以提供在测试中调用该代码的结果。这个假设很可能会在你面前爆炸,尤其是当你升级库版本时——测试通过,生产中断。
相反,为它编写一个 Adapter,然后在测试使用它的单元时使用它的模拟实例。适配器将您的代码与外界分开。要测试适配器本身,您必须编写一个 集成测试 ,它启动 spark(或适配器的任何实现)并检查适配器是否正常工作。
因此,您的适配器可能包含您在上面描述的功能,您需要编写一个集成测试来对照真实的 Spark 对其进行检查。但是,当您使用适配器时,您可以模拟它。
trait DataProcessor {
def filterData(SqlContext context, tableName): DataFrame
}
class SparkDataProcessor extends DataProcessor {
override def filterData(SqlContext context, tableName): DataFrame = {
...
}
}
以及使用它的 class 的测试:
class MyThingieTest extends Spec {
"should use the data processor" >> {
val mockDataProcessor = mock[DataProcessor]
mockDataProcessor.filterData(context, tableName) returns ...
MyThingie(mockDataProcessor).doSomething must beEqualTo(...)
}
}
这样你可以指定什么适配器returns。
注意 - 确保不要在适配器 API 中泄漏第 3 方实现。它应该只 return 你的 数据结构。
Here 是另一篇讨论这个主题的好文章。
我正在使用 Scala 编写一个 Spark 应用程序,我正在尝试为一种将从 Hive table 加载数据的方法编写单元测试,对其进行一些处理并 return 结果为一个数据框。
方法如下图所示:
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)
}
我想知道如何模拟 SqlContext.table()
方法,以便我可以在调用它时提供一些测试数据,或者是否有任何其他方法可以使用 Scala 实现它?
不要嘲笑你没有的东西。
当您这样做时,您假设您知道该代码的行为方式,因此您可以提供在测试中调用该代码的结果。这个假设很可能会在你面前爆炸,尤其是当你升级库版本时——测试通过,生产中断。
相反,为它编写一个 Adapter,然后在测试使用它的单元时使用它的模拟实例。适配器将您的代码与外界分开。要测试适配器本身,您必须编写一个 集成测试 ,它启动 spark(或适配器的任何实现)并检查适配器是否正常工作。
因此,您的适配器可能包含您在上面描述的功能,您需要编写一个集成测试来对照真实的 Spark 对其进行检查。但是,当您使用适配器时,您可以模拟它。
trait DataProcessor {
def filterData(SqlContext context, tableName): DataFrame
}
class SparkDataProcessor extends DataProcessor {
override def filterData(SqlContext context, tableName): DataFrame = {
...
}
}
以及使用它的 class 的测试:
class MyThingieTest extends Spec {
"should use the data processor" >> {
val mockDataProcessor = mock[DataProcessor]
mockDataProcessor.filterData(context, tableName) returns ...
MyThingie(mockDataProcessor).doSomething must beEqualTo(...)
}
}
这样你可以指定什么适配器returns。 注意 - 确保不要在适配器 API 中泄漏第 3 方实现。它应该只 return 你的 数据结构。
Here 是另一篇讨论这个主题的好文章。