簡體   English   中英

Spark:Scala模擬,任務不可序列化

[英]Spark : Scala mocking, Task not serializable

我正在嘗試使用Mockito對一些Scala代碼進行單元測試。 我想在本地運行spark,即在我的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() ,用於比較兩個名為testDataFrametestSource數據幀之間的數據。 然后,它返回具有結果的另一個數據幀。 現在,在單元測試中,我監視MyScalaClass來創建testObject 然后,我創建testDataFrametestSource並將它們分配給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中監視或模擬火花行為?

默認情況下,模擬無法序列化,因為在單元測試中通常是代碼異味

您可以嘗試通過創建類似mock[MyType](Mockito.withSettings().serializable())類的mock[MyType](Mockito.withSettings().serializable())來啟用序列化,並查看當spark嘗試使用它時會發生什么。

順便說一句,我建議您使用Mockito-scala而不是傳統的Mockito,因為它可以為您節省一些其他問題

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM