当方法将函数作为参数时 Mockito 验证失败
Mockito verify fails when method takes a function as argument
我有一个 Scala 测试,它使用 Mockito 来验证是否调用了某些 DataFrame 转换。我把它分解成这个简单的有问题的例子
import org.apache.spark.sql.DataFrame
import org.scalatest.funsuite.AnyFunSuite
import org.apache.spark.sql.functions._
import org.mockito.{Mockito, MockitoSugar}
class SimpleTest extends AnyFunSuite{
def withGreeting(df: DataFrame):DataFrame = {
df.withColumn("greeting", lit("hello"))
}
test("sample test") {
val mockDF = MockitoSugar.mock[DataFrame]
val mockDF2 = MockitoSugar.mock[DataFrame]
MockitoSugar.doReturn(mockDF2).when(mockDF).transform(withGreeting)
mockDF.transform(withGreeting)
val orderVerifier = Mockito.inOrder(mockDF)
orderVerifier.verify(mockDF).transform(withGreeting)
}
}
我试图断言转换是在我的 mockDF 上调用的,但它失败了
Argument(s) are different! Wanted:
dataset.transform(<function1>);
-> at org.apache.spark.sql.Dataset.transform(Dataset.scala:2182)
Actual invocations have different arguments:
dataset.transform(<function1>);
为什么在这种情况下验证会失败?
您需要将 transform
的 lambda 表达式参数保存为 val
以便正确测试并将其传递给所有 transform
调用:
def withGreeting(df: DataFrame):DataFrame = {
df.withColumn("greeting", lit("hello"))
}
test("sample test") {
val mockDF = MockitoSugar.mock[DataFrame]
val mockDF2 = MockitoSugar.mock[DataFrame]
val withGreetingExpression = df => withGreeting(df)
MockitoSugar.doReturn(mockDF2).when(mockDF).transform(withGreetingExpression)
mockDF.transform(withGreetingExpression)
val orderVerifier = Mockito.inOrder(mockDF)
orderVerifier.verify(mockDF).transform(withGreetingExpression)
}
Mockito 需要为模拟函数调用提供相同(或相等)的参数。当您传递 lambda 表达式而不保存每次调用时 transform(withGreeting)
创建新对象 Function[DataFrame, DataFrame]
transform(withGreeting)
等同于:
transform(new Function[DataFrame, DataFrame] {
override def apply(df: DataFrame): DataFrame = withGreeting(df)
})
并且它们彼此不相等 - 这是错误消息的原因:
Argument(s) are different!
例如尝试执行:
println(((df: DataFrame) => withGreeting(df)) == ((df: DataFrame) => withGreeting(df))) //false
您可以在 java 中阅读更多关于对象相等性的信息(在 scala 中它是相同的):
我有一个 Scala 测试,它使用 Mockito 来验证是否调用了某些 DataFrame 转换。我把它分解成这个简单的有问题的例子
import org.apache.spark.sql.DataFrame
import org.scalatest.funsuite.AnyFunSuite
import org.apache.spark.sql.functions._
import org.mockito.{Mockito, MockitoSugar}
class SimpleTest extends AnyFunSuite{
def withGreeting(df: DataFrame):DataFrame = {
df.withColumn("greeting", lit("hello"))
}
test("sample test") {
val mockDF = MockitoSugar.mock[DataFrame]
val mockDF2 = MockitoSugar.mock[DataFrame]
MockitoSugar.doReturn(mockDF2).when(mockDF).transform(withGreeting)
mockDF.transform(withGreeting)
val orderVerifier = Mockito.inOrder(mockDF)
orderVerifier.verify(mockDF).transform(withGreeting)
}
}
我试图断言转换是在我的 mockDF 上调用的,但它失败了
Argument(s) are different! Wanted:
dataset.transform(<function1>);
-> at org.apache.spark.sql.Dataset.transform(Dataset.scala:2182)
Actual invocations have different arguments:
dataset.transform(<function1>);
为什么在这种情况下验证会失败?
您需要将 transform
的 lambda 表达式参数保存为 val
以便正确测试并将其传递给所有 transform
调用:
def withGreeting(df: DataFrame):DataFrame = {
df.withColumn("greeting", lit("hello"))
}
test("sample test") {
val mockDF = MockitoSugar.mock[DataFrame]
val mockDF2 = MockitoSugar.mock[DataFrame]
val withGreetingExpression = df => withGreeting(df)
MockitoSugar.doReturn(mockDF2).when(mockDF).transform(withGreetingExpression)
mockDF.transform(withGreetingExpression)
val orderVerifier = Mockito.inOrder(mockDF)
orderVerifier.verify(mockDF).transform(withGreetingExpression)
}
Mockito 需要为模拟函数调用提供相同(或相等)的参数。当您传递 lambda 表达式而不保存每次调用时 transform(withGreeting)
创建新对象 Function[DataFrame, DataFrame]
transform(withGreeting)
等同于:
transform(new Function[DataFrame, DataFrame] {
override def apply(df: DataFrame): DataFrame = withGreeting(df)
})
并且它们彼此不相等 - 这是错误消息的原因:
Argument(s) are different!
例如尝试执行:
println(((df: DataFrame) => withGreeting(df)) == ((df: DataFrame) => withGreeting(df))) //false
您可以在 java 中阅读更多关于对象相等性的信息(在 scala 中它是相同的):