我正在尝试为一些 Android 代码编写单元测试,以查找 Intent
对象中存在的特定键。作为测试的一部分,我正在创建一个 Intent
对象并向其添加一个 String。但是,当我使用下面的代码时,我的变量被初始化为空:
val data = Intent().putExtra("key", "value")
// data is null
如果我把它分成两行,它工作得很好:
val data = Intent()
data.putExtra("key", "value")
// data is non-null and contains my key/value
Kotlin 语言的什么特性导致了这种情况的发生?
注意 putExtra()
返回一个 Intent
对象。来自 Android 来源:
public @NonNull Intent putExtra(String name, String value) {
if (mExtras == null) {
mExtras = new Bundle();
}
mExtras.putString(name, value);
return this;
}
在第一种情况下,推断类型是 Intent!
。我的印象是这只是意味着它是一个 Intent
或一个 Intent?
但 Kotlin 不想让开发人员对 Java 平台类型感到疯狂。尽管如此,鉴于 putExtra()
返回一个非空值,我希望 data
的实际值是非空的。
最佳答案
简短的回答是@CommonsWare 和@TheWanderer 在评论中提到的:我的测试类在 test/
目录中,所以它使用模拟的 Intent
实现真实的东西。
当我将测试移动到 androidTest/
目录时,一切都按预期进行。观察到的行为与 Kotlin 无关。
关于为什么这如此令人困惑的一些额外信息......
首先,我写错了:
val data = Intent() data.putExtra("key", "value") // data is non-null and contains my key/value
data
变量是 非空,但它实际上并不包含我的键/值对。我使用的模拟 Intent
实现正在删除 putExtra()
调用。
那么,为什么我的测试通过了?
我决定深入研究的一个特定测试是测试负面情况(当 Intent
中出现的 key 不是预期的 key 时)。但我没有传递一个带有错误键的 Intent,我传递的是一个根本没有键的 Intent。但是,无论哪种方式,预期的 key 都不存在,并且该方法返回 false
。
正例(所需 key 实际上被传递给putExtra()
)失败并出现AssertionError
。太遗憾了,我没有选择这个来仔细检查。
我的主要项目显然已通过 returnDefaultValues = true
gradle 选项将 Intent.putExtra()
作为空操作 stub 。当我创建一个新项目并尝试重现此问题时,我收到一个非常明显的错误:
java.lang.RuntimeException: Method putExtra in android.content.Intent not mocked. See http://g.co/androidstudio/not-mocked for details. at android.content.Intent.putExtra(Intent.java) at com.example.stackoverflow.IntentTest.test(IntentTest.kt:12)
不幸的是,使用模拟的 putExtra()
,我从未收到过这条有用的消息。
关于android - Kotlin - 为什么这个变量在初始化后为空?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54136260/