JUnit4 TextUtils.isEmpty() 给出的结果与 String.isEmpty() 不同

JUnit4 TextUtils.isEmpty() gives different result than String.isEmpty()

我知道这很奇怪,但这就是我所拥有的。

我正在编写单元测试来检查 Android 应用程序的逻辑。在测试执行期间,我看到它在那一行失败了:

if (!TextUtils.isEmpty(fromFile))

在此之前,if 语句 fromFile 等于 ""(空字符串),但不知何故它通过了它并打破了另一个不期望空字符串的逻辑。

深入调试我看到 fromFile.isEmpty() returns 正确的结果,但是 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;
}

我有以下配置: jdk1.8.0_77

我想避免应用程序中的整个逻辑来支持 String.isEmpty() 只是为了通过测试,因为我需要在 Android API 9 之前支持代码,其中String.isEmpty不可用,还TextUtils.isEmpty()多做。 任何有关澄清和建议的帮助都会有所帮助。

有人遇到过吗?我该如何解决?提前致谢!

对于将来要面对的人:

我在好人的帮助下弄明白了,它与 gradle 中的 android 单元测试配置有关:

testOptions {
    unitTests.returnDefaultValues = true
}

这为我指出了一个解决方案:摆脱您正在使用 JUnit(单元测试)测试的业务逻辑中的 android 依赖项。

我只是用 MyStringUtils.java class 中我自己的方法替换了 android.text.TextUtils,效果相同。

问题是默认 Android 方法执行 return 默认值,而 运行 单元测试,它实际上并没有检查 fromFile 值本身,而是return stub/default 值。

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
}