Kotlin - Почему эта переменная равна нулю после инициализации? - PullRequest
0 голосов
/ 10 января 2019

Я пытаюсь написать модульный тест для некоторого кода Android, который ищет определенный ключ, присутствующий в объекте Intent. В рамках моего теста я создаю объект Intent и добавляю к нему строку. Однако, когда я использую приведенный ниже код, моя переменная инициализируется нулем:

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 будет ненулевым.

1 Ответ

0 голосов
/ 10 января 2019

Короткий ответ - это то, что @CommonsWare и @TheWanderer упомянули в комментариях: мой тестовый класс находился в каталоге test/, поэтому он использовал фиктивную реализацию Intent вместо реальной.

Когда я перемещаю свой тест в каталог androidTest/, все работает как положено. Наблюдаемое поведение не имеет ничего общего с Котлиным.


Некоторая дополнительная информация о том, почему это так запутанно ...

Во-первых, я ошибся, когда написал следующее:

val data = Intent()
data.putExtra("key", "value")
// data is non-null and contains my key/value

Переменная data была ненулевой, но на самом деле она не содержала мою пару ключ / значение. В фиктивной реализации Intent, которую я использовал, отбрасывался putExtra() вызов.

Итак, почему мой тест прошел?

Один конкретный тест, на котором я решил углубиться, это проверка отрицательного случая (когда ключ, отличный от ожидаемого, присутствует в Intent). Но я не передавал Намерение с неправильным ключом, я передавал Намерение без ключей вообще. В любом случае, ожидаемый ключ отсутствует, и метод возвращает false.

Положительный случай (когда требуемый ключ на самом деле был передан putExtra()) потерпел неудачу с AssertionError. Жаль, что я не выбрал этот, чтобы исследовать.

Мой основной проект, по-видимому, отключил Intent.putExtra() как запрет на использование опции returnDefaultValues = true gradle. Когда я создаю новый проект и пытаюсь воспроизвести эту проблему, я получаю очень четкую ошибку:

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() я так и не получил это полезное сообщение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...