需要帮助使用Mockito和JUnit4编写unit testing

需要帮助使用Mockito和JUnit4编写以下代码的unit testing,

public class MyFragmentPresenterImpl { public Boolean isValid(String value) { return !(TextUtils.isEmpty(value)); } } 

我试过下面的方法:MyFragmentPresenter mMyFragmentPresenter

 @Before public void setup(){ mMyFragmentPresenter=new MyFragmentPresenterImpl(); } @Test public void testEmptyValue() throws Exception { String value=null; assertFalse(mMyFragmentPresenter.isValid(value)); } 

但是它返回下面的exception,

java.lang.RuntimeException:android.text.TextUtils中的方法isEmpty没有被模拟。 有关详细信息,请参阅http://g.co/androidstudio/not-mocked 。 在android.text.TextUtils.isEmpty(TextUtils.java)在….

Solutions Collecting From Web of "需要帮助使用Mockito和JUnit4编写unit testing"

由于JUnit TestCase类不能使用Android相关的API,我们必须对其进行模拟。
使用PowerMockito来模拟静态类。

在testing用例类上面添加两行,

 @RunWith(PowerMockRunner.class) @PrepareForTest(TextUtils.class) public class YourTest { } 

和设置代码

 @Before public void setup() { PowerMockito.mockStatic(TextUtils.class); PowerMockito.when(TextUtils.isEmpty(any(CharSequence.class))).thenAnswer(new Answer<Boolean>() { @Override public Boolean answer(InvocationOnMock invocation) throws Throwable { CharSequence a = (CharSequence) invocation.getArguments()[0]; return !(a != null && a.length() > 0); } }); } 

用我们自己的逻辑实现TextUtils.isEmpty()

另外,在app.gradle文件中添加依赖关系。

 testCompile "org.powermock:powermock-module-junit4:1.6.2" testCompile "org.powermock:powermock-module-junit4-rule:1.6.2" testCompile "org.powermock:powermock-api-mockito:1.6.2" testCompile "org.powermock:powermock-classloading-xstream:1.6.2" 

感谢BehelitException的回答。

这是@Exception提到的已知问题。 在我的情况下,我也偶然发现了相同的情况,但高级开发人员的build议决定使用Strings.isNullOrEmpty()而不是TextUtils.isEmpty() 。 原来是避免它的一个好方法。

更新:我应该更好地提到这个实用函数Strings.isNullOrEmpty()需要Guava库。

使用PowerMockito

把这个添加到你的类名上面,并且包含所有其他的CUT类名(被testing的类)

 @RunWith(PowerMockRunner.class) @PrepareForTest({TextUtils.class}) public class ContactUtilsTest { 

将此添加到您的@Before

 @Before public void setup(){ PowerMockito.mockStatic(TextUtils.class); mMyFragmentPresenter=new MyFragmentPresenterImpl(); } 

这将使PowerMockito为TextUtils中的方法返回默认值

您还必须添加相关的gradle dependencies

 testCompile "org.powermock:powermock-module-junit4:1.6.2" testCompile "org.powermock:powermock-module-junit4-rule:1.6.2" testCompile "org.powermock:powermock-api-mockito:1.6.2" testCompile "org.powermock:powermock-classloading-xstream:1.6.2" 

在Android Studio的情况下,在您的gradle文件中添加此行。

 android{ .... testOptions { unitTests.returnDefaultValues = true } } 

这是一个已知的问题,由于Android的testing基础中的一个条款,它说:

您可以使用JUnit TestCase类对不调用Android API的类进行unit testing。

当使用像Log或者TextUtils这样的类时,默认行为是有问题的。

总结一下:

  1. android.jar之前是模拟的,所以一些Android API的返回值可能不如预期。
  2. JUnit本身是java代码的一个单独的措施,所以尽量不要使用Android API方法。

资料来源: http : //www.liangfeizc.com/2016/01/28/unit-test-on-android/

我能够通过运行以下testing类来解决这个错误。

@RunWith(RobolectricGradleTestRunner.class)公共类MySimpleTest {…..一堆testing用例}

这个wiki页面更详细的解释https://github.com/yahoo/squidb/wiki/Unit-testing-with-model-objects

我用我的项目TextUtils.isEmpty(...)任何地方replace:

 /** * Util class to be used instead of Android classes for Junit tests. */ public class Utils { /** * Returns true if the string is null or 0-length. * @param str the string to be examined * @return true if str is null or zero length */ public static boolean isEmpty(@Nullable CharSequence str) { return str == null || str.length() == 0; } }