Android项目Assets文件JUnit测试抛出FileNotFoundException问题
问题分析与解决方案
核心问题
- 方法参数未被使用:
populateAbcFromAssets方法接收了fileName参数,但内部硬编码了"abc.json"作为打开的文件名,导致第一个测试用例传入空字符串时,方法依然尝试读取存在的abc.json,不会触发预期的FileNotFoundException,测试断言失败。 - 测试环境Assets资源缺失:使用
ApplicationProvider的Instrumented测试默认不会自动包含主工程的Assets文件,若src/androidTest/assets目录下没有abc.json,测试时会找不到文件,导致第二个测试用例抛出未预期的异常。
修复步骤
1. 修正方法实现,使用传入的文件名参数
修改AbcManager中的populateAbcFromAssets方法,将硬编码的文件名替换为传入的fileName参数:
fun populateAbcFromAssets(context: Context, fileName: String) { var inputStream: InputStream? = null try { // 替换为传入的fileName参数 inputStream = context.assets.open(fileName) val size: Int = inputStream.available() val buffer = ByteArray(size) inputStream.read(buffer) inputStream.close() val json = String(buffer, Charsets.UTF_8) val gson = Gson() abcList = gson.fromJson(json, Array<AbcDataClass>::class.java) } catch (e: FileNotFoundException) { throw e } finally { inputStream?.close() } }
2. 确保测试环境能访问Assets文件
有两种方式解决测试环境资源缺失问题:
- 手动复制文件:将主工程
src/main/assets/abc.json复制到src/androidTest/assets目录下。 - Gradle配置自动同步:在模块的
build.gradle(或build.gradle.kts)的android块中添加配置,让测试环境自动包含主工程的Assets资源:
android { // 其他配置... sourceSets { androidTest.assets.srcDirs += main.assets.srcDirs } }
3. 优化资源管理(可选)
使用Kotlin的use函数自动管理输入流,避免手动关闭流可能出现的资源泄漏问题,同时简化代码:
fun populateAbcFromAssets(context: Context, fileName: String) { context.assets.open(fileName).use { inputStream -> val size = inputStream.available() val buffer = ByteArray(size) inputStream.read(buffer) val json = String(buffer, Charsets.UTF_8) val gson = Gson() abcList = gson.fromJson(json, Array<AbcDataClass>::class.java) } }
use函数会在代码块执行完毕后自动关闭流,无论是否发生异常,同时open方法抛出的FileNotFoundException会直接向上传递,符合测试用例的预期。
内容的提问来源于stack exchange,提问作者Vinit ...
相关产品推荐
相关产品推荐

