android - Kotlin - 为什么这个变量在初始化后为空?

标签 android kotlin

我正在尝试为一些 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/

相关文章:

java - Android中的双重检查锁定

Android 应用在 Google Play 上私有(private)发布

Kotlin - 覆盖/实现类似数组的访问器函数

kotlin - 如何在 Kotlin Native 中使用 Http Request lib

java - Spring 5 和 Kotlin 1.1 协程 : Type rx. 调度程序不存在

java - Android 时间选择器对话框。设置时间超过当前时间时应用程序崩溃

android - 是否有关于在平板电脑上使用手势控制动画的教程/代码示例?

android - 如何在手机上实时记录来电/去电/未接来电

kotlin - 如何在 Kotlin 中运行编译的类文件?

kotlin - 如何将text/blob文件作为资源包含在Kotlin/Native中作为可执行文件一起编译?