我试图为访问/asset
中的文件的类创建一个测试单元,并且就我实验而言,如果不改变被测试类的逻辑,我认为没办法做到这一点
我想要完成的是创建一个环境,我可以将我的类指向我喜欢的资产文件(而不是最初在代码中指出的那个),这样我就可以用它运行多个测试,所以例如,如果我的原始代码看起来像:
ctx.getAssets().open("config.txt")
我可以改为打开
bogus_config.txt
ok_config.txt
nonexisting_config.txt
到目前为止,我已经尝试过:
MockContext
,但由于AssetManager
中的所有内容都是final
,我认为无法获得所需的文件RenamingDelegatingContext
,但前缀并不适用于资产档案...... 有没有更好的方法(例如某些Java Magik Reflection Trick(Tm))来实现我想要的目标?
尽管我对一般的单元测试非常陌生,但我知道我可以选择以下任何一种解决方案:
junit_
来记录它仅供测试例程使用(可能是我最终会做什么)但我仍然认为原来的问题可能会引起一些兴趣,所以欢迎提出任何建议
谢谢!
答案 0 :(得分:1)
> I see no way do that without altering the logic of the class being tested.
我同意,但更改很小:将代码ctx.getAssets().open("config.txt")
移动到受保护的方法InputStream openConfig(Context ctx)
中,您可以在测试中轻松覆盖/伪造/模拟。如果使用Eclipse或Androidstudio标记语句并执行context-menu Refactor / Extract-Method。
答案 1 :(得分:0)
您可以使用这种方式
class AssetsUtils {
companion object {
fun <T> loadResponse(
path: String,
tClass: Class<T>?,
isPrettyPrinting: Boolean? = false,
isUnitTest: Boolean? = true
): T {
val json = File(
"src/${if (isUnitTest == true) {
"test"
} else {
"androidTest"
}}/assets/${path}"
).bufferedReader().use {
it.readText()
}
val gson = GsonBuilder()
.serializeNulls()
.setPrettyPrinting()
.create()
val model = gson.fromJson(json, tClass)
if (isPrettyPrinting == true) {
println("Load Response ------------------------------------------------------------------------------------------------")
println()
println("Response file: $path")
println(gson.toJson(model))
println()
println("Model: $model")
println()
println("--------------------------------------------------------------------------------------------------------------")
}
return model
}
}
}
示例: “ C://ProjectA/app/src/test/asstes/mockApi/folder1/user.json”中的文件
AssetsUtils.loadResponse(
"mockApi/folder1/user.json",
UserModel::class.java
)