2016-04-25 8 views
6

Я знаю, что это странно, но это то, что у меня есть.JUnit4 TextUtils.isEmpty() дает отличный результат, чем String.isEmpty()

enter image description here

Я пишу модульный тест, чтобы проверить свою логику для Android приложения. Во время выполнения теста, я вижу, что он не будет работать на этой линии:

if (!TextUtils.isEmpty(fromFile))

До этого if заявление FromFile является равно "" (пустая строка), но как-то она проходит через него и разрывы с другой логикой, Безразлично Не ожидайте пустую строку.

Дайвинг в отладку Я видел, что fromFile.isEmpty() возвращает правильный результат, но TextUtils.isEmpty(fromFile) говорит, что он не пуст.

Открытый исходный код, я вижу:

public static boolean isEmpty(@Nullable CharSequence str) { 
    if (str == null || str.length() == 0) 
     return true; 
    else 
     return false; 
} 

и String.java:

public boolean isEmpty() { 
    return value.length == 0; 
} 

Я следующий configutation: JDK 1.8.0_77

Я хотел бы избежать всей логику в приложении для поддержки String.isEmpty(), чтобы пройти тест, так как мне нужно поддерживать код перед Android API 9, где String.isEmpty недоступен, и al поэтому TextUtils.isEmpty() сделать больше. Любая помощь с разъяснениями и рекомендациями была бы полезна.

С кем-нибудь сталкивались? Как его исправить? Заранее спасибо!

ответ

7

Для тех, кто столкнется его в будущем:

Я выяснял это благодаря помощи хорошего человека, что связано с андроида тестовой конфигурации устройства в Gradle:

testOptions { 
    unitTests.returnDefaultValues = true 
} 

который указал я к решению: избавьтесь от зависимостей android в логике buisness, которую вы тестируете с помощью JUnit (unit test).

Я просто заменил android.text.TextUtils своим собственным методом, который находится в классе MyStringUtils.java, который делает то же самое.

Проблема заключалась в том, что в результате отказов Android-методы действительно возвращали значения глухонемых при запуске модульного теста, и на самом деле он не проверял значение fromFile, а не возвращал значение stub/default.

+0

Но это thi s решение? Я имею в виду, что для этого случая у вас есть только TextUtils, но что, если вы используете SparsArrays и некоторые другие пользовательские утилиты, предоставляемые Android? – karate

+0

Идея чистых тестов JUnit заключается в том, что они должны использоваться против POJO (обычный старый Java-объект). 'SparseArrays' не являются старой Java. Если у вас есть это, вы можете пойти с http://robolectric.org/, который полностью соответствует требованиям google https://developer.android.com/training/testing/fundamentals.html –

1

TextUtils не является методом JUnit.Если вам необходимо манипулировать с TextUtils.isEmpty ответом или другим способом, вы можете издеваться это нравится:

mockStatic(TextUtils.class); 
when(TextUtils.isEmpty(any(CharSequence.class))).thenAnswer(new Answer<Boolean>() { 
     @Override 
     public Boolean answer(InvocationOnMock invocation) throws Throwable { 
      CharSequence str = (CharSequence) invocation.getArguments()[0]; 
      if (str == null || str.length() == 0) 
       return true; 
      else 
       return false; 
     } 
    }); 

Не забудьте добавить TextUtils к PrepareForTest списку:

@PrepareForTest({TextUtils.class}) 

Кроме упомянутого выше метода работает для returnDefaultValues конфигурация:

testOptions { 
    unitTests.returnDefaultValues = true 
} 
+0

К сожалению, мы не используем ' Powermock' и 'mockStatic' неприменимы. Мы перешли к другой архитектуре, где наши классы Java являются POJO и не имеют каких-либо зависимостей от android. Мы также отошли от статических методов, таких как «Utils.doSomething» и удалили одиночные точки. Это дает нам больший контроль над DI и тестированием. Насколько я знаю, кодеки по-прежнему не поддерживают 'PowerMockito'. Но спасибо за ваш ответ, я думаю, что многие разработчики посчитают это полезным. –

Смежные вопросы