2017-12-23 49 views
0

を実行しているときにように私は、私たちのテスト環境に(Guiceの付き)mockitoを追加しました:ClassCastExceptionがスパークテスト

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のための(取得上書きされます私たち自身のクラス)であるとsparkSessionを構築します。私たちはそうのようなテストinjectorWithMocks、私は注入sparkSessionとサービスを :

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

私はのIntelliJからテストを実行すると、すべてが正常に動作しますが、私には、例えば、SBTのコマンドラインから実行する場合:

sbt "testOnly *ClickoutEnrichmentServiceTest" 

私は、次のエラーが表示さ:私はこの問題について、いくつかのチケットを読みましたが、彼らはすべてのスパークCLUSTを実行しているに関連していた

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 

をローカルでもテストモードでもありません。

誰かがこのエラーの原因とその対処方法について説明してください。私もこれに走った

おかげ ニール

答えて

0

。私は最終的にこの質問を見つけましたMockito's mock throw ClassNotFoundException in Spark application @ K.Chenから

彼は彼の問題の解決策を提供します。つまり、あなたのコードに 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 source

をおそらくマスター対執行におけるクラスローダは違うのですか?