簡體   English   中英

運行Spark測試時發生ClassCastException

[英]ClassCastException when running Spark test

我已經將mockito(與Guice一起)添加到我們的測試環境中,如下所示:

class SparkModuleWithMocks extends AbstractModule with JsonFormats {
override def configure(): Unit = {
  //bind(classOf[TrafficFilterRules]).toInstance(trafficFilterRulesMock)
  bind(classOf[TrafficFilterRules]).toProvider(new Provider[TrafficFilterRules]{
    override def get(): TrafficFilterRules = {
      val trafficFilterRulesMock: TrafficFilterRules = mock[TrafficFilterRules](withSettings().serializable())
      val stream = getClass.getResourceAsStream("/trafficFilterRules.json")
      val lines = scala.io.Source.fromInputStream( stream ).getLines.mkString
      val array = parse(lines).extract[List[FilterRules]].toArray
      when(trafficFilterRulesMock.trafficFilterRulesTable).thenReturn(array)
      trafficFilterRulesMock
    }
  })
  bind(classOf[SiteTable]).toProvider(new Provider[SiteTable]{
    override def get(): SiteTable = {
      val siteTableMock: SiteTable = mock[SiteTable](withSettings().serializable())
      val stream = getClass.getResourceAsStream("/siteDomains.json")
      val lines = scala.io.Source.fromInputStream( stream ).getLines.mkString
      val array = parse(lines).extract[List[SiteDomain]].toArray
      when(siteTableMock.siteDomains).thenReturn(array)
      siteTableMock
    }
  })
  bind(classOf[SparkSession]).toProvider(classOf[SparkSessionProvider])
}
}

val injectorWithMocks: Injector = Guice.createInjector(new SparkModuleWithMocks)

SparkSessionProvider是我們自己的類,它重寫guice的get()並構建sparkSession。 使用InjectorWithMocks,我像這樣注入sparkSession和我們測試的服務:

val sparkSession = injector.instance[SparkSession]
val clickoutService = injectorWithMocks.instance[ClickoutEnrichmentService]

當我從Intellij運行測試時,一切正常,但是當我從sbt命令行運行時,例如:

 sbt "testOnly *ClickoutEnrichmentServiceTest"

我收到以下錯誤:

org.apache.spark.SparkException: Job aborted due to stage failure: 
Task 0 in stage 49.0 failed 1 times, most recent failure: Lost task 0.0 in 
stage 49.0 (TID 68, localhost, executor driver): 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

我已經閱讀了幾張有關此問題的票證,但它們都與運行Spark Cluster有關,而不是本地或測試模式。

有人可以解釋造成此錯誤的原因是什么,以及解決該錯誤的正確方向是什么?

謝謝尼爾

我也遇到了這個。 我最終 @ K.Chen的Spark應用程序中發現了Mockito的模擬拋出ClassNotFoundException問題

他為他的問題提供了解決方案,即在您的代碼中使用mock[SiteTable](withSettings().serializable(SerializableMode.ACROSS_CLASSLOADERS)) 也就是說,傳遞額外的參數SerializableMode.ACROSS_CLASSLOADERS

不幸的是,正如他在問題中指出的那樣,他不確定為什么這可以解決問題。

在Mockito 2.13.1的SerializableMode的源代碼中,我們找到以下注釋: /** * Useful if the mock is deserialized in a different classloader / vm. */ @Incubating ACROSS_CLASSLOADERS /** * Useful if the mock is deserialized in a different classloader / vm. */ @Incubating ACROSS_CLASSLOADERS

也許執行者與主者中的類加載器是不同的?

暫無
暫無

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

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