Scala单元测试:从InputStream创建File对象解决Jenkins构建报错
解决Jar环境下ClassPathResource转File的测试问题
问题根源
本地运行时,测试资源是文件系统里的真实文件,ClassPathResource.getFile()能正常获取;但Jenkins构建后资源被打包进Jar包,Jar里的资源并非磁盘上的真实File对象,因此抛出FileNotFoundException。
三种可行解决方案
1. 将InputStream写入临时文件(最直接的兼容方案)
把ClassPathResource的InputStream内容复制到一个临时File里,用完自动删除,完美适配本地和Jar两种环境。
用Java NIO实现(无需额外依赖)
import org.springframework.core.io.ClassPathResource import java.nio.file.{Files, StandardCopyOption} val resource = new ClassPathResource("input/mock.txt") // 创建临时文件 val tempFile = Files.createTempFile("test-mock", ".txt").toFile try { // 将输入流内容写入临时文件 Files.copy(resource.getInputStream, tempFile.toPath, StandardCopyOption.REPLACE_EXISTING) // 这里把tempFile加入列表,传给被测试方法 } finally { // 测试结束后删除临时文件 tempFile.delete() }
用Apache Commons IO简化代码(需引入依赖)
如果项目已经依赖commons-io,可以用工具类快速实现:
import org.springframework.core.io.ClassPathResource import org.apache.commons.io.FileUtils val resource = new ClassPathResource("input/mock.txt") val tempFile = File.createTempFile("test-mock", ".txt") try { FileUtils.copyInputStreamToFile(resource.getInputStream, tempFile) // 使用tempFile进行测试 } finally { tempFile.delete() }
2. 修改被测试方法的依赖(更优雅的长期方案)
如果有权限修改被测试方法的参数类型,建议把List[File]改成List[org.springframework.core.io.Resource]或List[InputStream]。这样直接传入ClassPathResource对象即可,完全避开File的限制,同时Spring的Resource接口本身就支持Jar内资源的读取。
示例修改后的方法签名:
// 原方法 def processFiles(files: List[File]): Unit // 修改后 def processResources(resources: List[org.springframework.core.io.Resource]): Unit
3. Mock File对象(适合无需真实文件内容的场景)
如果测试只需要验证方法是否接收到File列表,不需要读取文件内容,可以用Mockito直接Mock File对象:
import org.mockito.Mockito._ import java.io.File val mockFile = mock(classOf[File]) // Mock必要的方法,比如文件名 when(mockFile.getName).thenReturn("mock.txt") // 将mockFile加入列表传给被测试方法 val testFiles = List(mockFile) // 执行测试并验证
内容的提问来源于stack exchange,提问作者Mandroid
相关产品推荐
相关产品推荐

