Spark udfs内部使用的模拟功能

时间:2019-12-17 07:03:32

标签: scala maven apache-spark mockito user-defined-functions

我有一个用户定义的函数,如下:

def myFunc(df: DataFrame, column_name: String, func:(String)=>String = myFunc) = {
    val my_udf = udf{ (columnValue: String) => func(columnValue) }
    df.withColumn("newColumn", my_udf(df(column_name)))
}

现在,在编写测试用例时,我想模拟myFunc。我正在使用Mockito进行测试。 所以我用

创建了一个模拟函数
var fmock = mock[(String)=>String]
when(fmock(any[String])).thenReturn("default_string_write_value")

但是,当我尝试通过此fmock时,出现以下异常:java.io.NotSerializableException

因此,我尝试通过声明如下使模拟序列化:

var fmock = mock[(String)=>String](Mockito.withSettings().serializable())

现在,当我在myFunc返回的数据帧上调用collect时,会收到以下异常: java.lang.ClassCastException: cannot assign instance of scala.collection.immutable.List$SerializationProxy to field org.apache.spark.rdd.RDD.org$apache$spark$rdd$RDD$$dependencies_ of type scala.collection.Seq in instance of org.apache.spark.rdd.MapPartitionsRDD

当我尝试执行收集操作时,将获得此错误。

另外,一件奇怪的事情正在发生。该测试用例通过了IntelliJ(我正在使用的IDE),但是当我使用Maven运行它时失败了。

测试用例如下(假设我已经有一个数据帧-TESTDF,其中有列-COL1,COL2,COL3):

val fmock = mock[(String)=>String](Mockito.withSettings().serializable())
when(fmock(any[String])).thenReturn("default_string_write_value")
val ansDf = myFunc(TESTDF, COL1, fmock)
var rowValueArray = ansDf.select("newColumn").collect.map(x => x(0).asInstanceOf[String])
assert(rowValueArray(0)=="default_string_write_value")

请注意,我正在使用Spark版本2.3.3和scala 2.11.8。该应用程序运行良好,问题仅在于测试用例(在Maven中也是如此)。

0 个答案:

没有答案