scala – 为什么方法参数会导致Mockito出现NotSerializableExcep
我有一些使用spark运行的
Scala代码,但我简化了它们:
// Not Serializable class Config object FileReader extends FileReader class FileReader extends Serializable { def read(config: Config): String = config.getClass.toString } object Task extends Task(FileReader) class Task(fileReader: FileReader) extends Serializable { def execute(config: Config): Unit = { fileReader.read(config) } } 不是Config不可序列化. 我想为它们编写一些测试,并且Task的实例需要是Serializable,因为它可以被序列化并发送给spark worker. 我使用此函数来检查对象是否可以序列化: def checkSerializable(obj: AnyRef,name: String) = { println("### checking " + name + ": " + obj.getClass) new ObjectOutputStream(new ByteArrayOutputStream()).writeObject(obj) println(name + " ok") } 首先让我们检查是否可以序列化正常的Task实例: val task = new Task(new FileReader) checkSerializable(task,"no-mockito") 输出: ### checking no-mockito: class Task no-mockito ok 似乎没问题. 但我想用Mockito模拟FileReader,所以我的代码将是: val fileReader = Mockito.mock(classOf[FileReader]) val config = Mockito.mock(classOf[Config]) Mockito.when(fileReader.read(config)).thenReturn("mocked") val task = new Task(fileReader) checkSerializable(task,"with-mockito1") 它报告Config不可序列化的错误: ### checking with-mockito1: class Task java.io.NotSerializableException: Config$$EnhancerByMockitoWithCGLIB$$c7dcb0a5 at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1165) at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1359) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1155) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1535) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1496) 这很奇怪,因为config只是一些方法参数,而不是类字段! 我修改了我的代码以使配置可序列化: val fileReader = Mockito.mock(classOf[FileReader]) val config = Mockito.mock(classOf[Config],Mockito.withSettings().serializable()) Mockito.when(fileReader.read(config)).thenReturn("mocked") val task = new Task(fileReader) checkSerializable(task,"with-mockito2") 它仍然失败,另一个NotSerializableException: ### checking with-mockito2: class Task java.io.NotSerializableException: org.mockito.internal.creation.DelegatingMethod at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1165) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1535) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1496) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1413) 在使用Mockito时,不确定为什么配置实例会包含在任务中?以及如何避免它? 演示项目:https://github.com/freewind/mockito-serialization-issue,你可以克隆它并运行demo / MockitoDemo.scala 更新: 另一个值得注意的事情是:如果我删除这一行 fileReader.read(config) 来自Task,这意味着任务将是: class Task(fileReader: FileReader) extends Serializable { def execute(config: Config): Unit = { // removed this line: fileReader.read(config) } } 不再抛出NotSerializableException(我没有更改测试代码) 解决方法
您可能需要使FileReader模拟序列化也尝试:
val fileReader = Mockito.mock(classOf[FileReader],Mockito.withSettings().serializable()) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |