Android Base64 кодирует и декодирует возврат null в Unit Test

Я пытаюсь декодировать строку в кодировке Base64 в Android с помощью http://developer.android.com/reference/android/util/Base64.html класса.

Оба метода encodeToString и decode возвращают значение null, и я понятия не имею, что не так, вот мой код для декодирования:

// Should decode to "GRC"
String friendlyNameBase64Encoded = "R1JD";

// This returns null
byte[] friendlyNameByteArray = Base64.decode(friendlyNameBase64Encoded, Base64.DEFAULT);

// Fails with NullPointerException
String friendlyName = new String(friendlyNameByteArray, "UTF-8");

Я использую Android API 23.1.0

Ответ 1

У меня была такая же проблема в моих модульных тестах. Я не понимал, что класс Base64, который я использую, является частью Android API, поэтому

Вы не можете использовать android.util.Base64 в обычном тесте JUnit, это должен быть тест Instrumentation.

Однако, если вы действительно хотите использовать его как unit test, вместо этого вы можете использовать класс Apache Commons Base64. Включите его в Gradle build:

// https://mvnrepository.com/artifact/org.apache.commons/commons-collections4
compile group: 'org.apache.commons', name: 'commons-collections4', version: '4.1'

И затем немного другое использование,

Ответ 2

Следите за учебными пособиями по android и записями unit test, пока вам нужны только тесты Unit без использования некоторых файлов Android.

В вашем случае вы зависите от android.Base64. У меня была аналогичная проблема, и сработали тестовые классы из src/testsrc/androidTest. Те тесты выполняются на виртуальной машине или на реальном устройстве Android. Я не заметил разницу при первом взгляде.

Ответ 3

Вы можете использовать Robolectric Runner

  • Добавьте зависимость в build.gradle:

    testCompile 'org.robolectric:robolectric:X.X.X'
    
  • Добавьте эту строку в свой тестовый класс:

    import org.junit.runner.RunWith;
    import org.robolectric.RobolectricTestRunner;
    
    @RunWith(RobolectricTestRunner.class)
    public class MyTestingClassTest {
        ...
    }
    

Ответ 4

Как уже говорилось, android.util.Base64.decode возвращает нуль в тестовом жгуте из-за этого параметра в файле сборки:

testOptions {
    unitTests.returnDefaultValues = true
}

Чтобы не включать другие библиотеки, вы можете использовать java.util.Base64, который доступен только в Java8 и Android 26 и выше. Если вы уже нацелились на 26+, просто переключитесь на этот метод, но если вам нужно нацелиться на более ранние SDK, вы можете проверить нулевой возврат и вместо этого вызвать метод test-harness:

// Required because Android classes return null in desktop unit tests
@TargetApi(26)
private fun testHarnessDecode(s : String) : ByteArray {
    return java.util.Base64.getDecoder().decode(s)
}

Я бы предпочел сделать это, чем тянуть дополнительные библиотечные зависимости, но YMMV.