Spark: издевательство над Scala, задача не сериализуема - PullRequest
0 голосов
/ 17 декабря 2018

Я пытаюсь использовать mockito для модульного тестирования некоторого скала-кода.Я хочу запустить искру локально, то есть в моей IntelliJ IDE.Вот пример

class MyScalaSparkTests extends FunSuite with BeforeAndAfter with MockitoSugar with java.io.Serializable{

  val configuration:SparkConf  = new SparkConf()
    .setAppName("Your Application Name")
    .setMaster("local");
  val sc = new SparkContext(configuration);
  lazy val testSess = SparkSession.builder.appName("local_test").getOrCreate()
  test ("test service") {
    import testSess.implicits._
    // (1) init
    val testObject = spy(new MyScalaClass(<some args>))
    val testDf = testSess.emptyDataset[MyCaseClass1].toDF()
    testDf.union(Seq(MyCaseClass(<some args>)).toDF())
    testObject.testDataFrame = testDf
    val testSource = testSess.emptyDataset[MyCaseClass2].toDF()
    testSource.union(Seq(MyCaseClass2(<some args>)).toDF())
    testObject.setSourceDf(testSource)
    val testRes = testObject.someMethod()

    val r = testRes.take(1)
    println(r)

  }

}

, так что в основном вот что я пытаюсь сделать

MyScalaClass имеет someMethod(), который сравнивает данные между двумя фреймами данных, называемыми testDataFrame и testSource.Затем он возвращает другой фрейм данных, который имеет результаты.Теперь в моем модульном тесте я шпионю за MyScalaClass, чтобы создать testObject.Затем я создаю testDataFrame и testSource и присваиваю их testObject.Наконец, я вызываю testObject.someMethod().

Теперь в отладчике, в этой строке

val r = testRes.take(1)

Я вижу, что testRes является Dataset, следовательно, что-то возвращается методом,Но когда я пытаюсь take что-то из этого получить, чтобы проверить результаты, я получаю

Task not serializable
org.apache.spark.SparkException: Task not serializable

и дальше по трассе стека

Caused by: java.io.NotSerializableException: org.mockito.internal.creation.DelegatingMethod
Serialization stack:
    - object not serializable (class: org.mockito.internal.creation.DelegatingMethod, value: org.mockito.internal.creation.DelegatingMethod@a97f2bff)
    - field (class: org.mockito.internal.invocation.InterceptedInvocation, name: mockitoMethod, type: interface org.mockito.internal.invocation.MockitoMethod)
    - object (class org.mockito.internal.invocation.InterceptedInvocation, bSV2PartValidator.toString();)
    - field (class: org.mockito.internal.invocation.InvocationMatcher, name: invocation, type: interface org.mockito.invocation.Invocation)
    - object (class org.mockito.internal.invocation.InvocationMatcher, bSV2PartValidator.toString();)
    - field (class: org.mockito.internal.stubbing.InvocationContainerImpl, name: invocationForStubbing, type: interface org.mockito.invocation.MatchableInvocation)
    - object (class org.mockito.internal.stubbing.InvocationContainerImpl, invocationForStubbing: bSV2PartValidator.toString();)
    - field (class: org.mockito.internal.handler.MockHandlerImpl, name: invocationContainer, type: class org.mockito.internal.stubbing.InvocationContainerImpl)
    - object (class org.mockito.internal.handler.MockHandlerImpl, org.mockito.internal.handler.MockHandlerImpl@47c019d7)
    - field (class: org.mockito.internal.handler.NullResultGuardian, name: delegate, type: interface org.mockito.invocation.MockHandler)
    - object (class org.mockito.internal.handler.NullResultGuardian, org.mockito.internal.handler.NullResultGuardian@7222e168)
    - field (class: org.mockito.internal.handler.InvocationNotifierHandler, name: mockHandler, type: interface org.mockito.invocation.MockHandler)
    - object (class org.mockito.internal.handler.InvocationNotifierHandler, org.mockito.internal.handler.InvocationNotifierHandler@1e4f8430)
    - field (class: org.mockito.internal.creation.bytebuddy.MockMethodInterceptor, name: handler, type: interface org.mockito.invocation.MockHandler)
    - object (class org.mockito.internal.creation.bytebuddy.MockMethodInterceptor, org.mockito.internal.creation.bytebuddy.MockMethodInterceptor@34d08905)
    - field (class: com.walmart.labs.search.signals.validators.BSV2PartValidator$MockitoMock$213785213, name: mockitoInterceptor, type: class org.mockito.internal.creation.bytebuddy.MockMethodInterceptor)
    - object (class com.walmart.labs.search.signals.validators.BSV2PartValidator$MockitoMock$213785213, com.walmart.labs.search.signals.validators.BSV2PartValidator$MockitoMock$213785213@7f289126)
    - field (class: com.walmart.labs.search.signals.validators.BSV2PartValidator$$anonfun$1, name: $outer, type: class com.walmart.labs.search.signals.validators.BSV2PartValidator)
    - object (class com.walmart.labs.search.signals.validators.BSV2PartValidator$$anonfun$1, <function1>)
    - element of array (index: 1)
    - array (class [Ljava.lang.Object;, size 7)
    - field (class: org.apache.spark.sql.execution.WholeStageCodegenExec$$anonfun$8, name: references$1, type: class [Ljava.lang.Object;)
    - object (class org.apache.spark.sql.execution.WholeStageCodegenExec$$anonfun$8, <function2>)
    at org.apache.spark.serializer.SerializationDebugger$.improveException(SerializationDebugger.scala:40)
    at org.apache.spark.serializer.JavaSerializationStream.writeObject(JavaSerializer.scala:46)
    at org.apache.spark.serializer.JavaSerializerInstance.serialize(JavaSerializer.scala:100)
    at org.apache.spark.util.ClosureCleaner$.ensureSerializable(ClosureCleaner.scala:295)
    ... 78 more

Что я делаю не так?Возможно ли даже шпионить или высмеивать поведение искры в IDE?

1 Ответ

0 голосов
/ 17 декабря 2018

Мок по умолчанию не сериализуемы, так как это обычно - запах кода в модульном тестировании.

Вы можете попробовать включить сериализацию, создав макет наподобие mock[MyType](Mockito.withSettings().serializable()) и посмотреть, что произойдет, когда spark попытается использовать его.

Кстати, я рекомендую вам использовать mockito-scala вместо традиционного mockito, поскольку это может избавить вас от некоторых других проблем

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...