0

I am trying to write a unit test for my class, but I am getting the following error

java.lang.RuntimeException: Method isEmpty in android.text.TextUtils not mocked. See http://g.co/androidstudio/not-mocked for details.

at android.text.TextUtils.isEmpty(TextUtils.java)
at com.mvvm.testmvvm.Model.User.isValidUser(User.java:37)
at com.mvvm.testmvvm.LoginViewModelTest.isValidUser_Test(LoginViewModelTest.java:15)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMainV2.main(AppMainV2.java:131)

this is my class

public class User {

    private String  mEmail;
    private String  mPassword;

    public User() {
    }

    public User(String mEmail, String mPassword) {
        this.mEmail = mEmail;
        this.mPassword = mPassword;
    }

    public String getEmail() {
        return mEmail;
    }

    public void setEmail(String mEmail) {
        this.mEmail = mEmail;
    }

    public String getPassword() {
        return mPassword;
    }

    public void setPassword(String mPassword) {
        this.mPassword = mPassword;
    }

    public int isValidUser () {

        if (TextUtils.isEmpty(getEmail()) == true)
            return 0;
        else if (!Patterns.EMAIL_ADDRESS.matcher(getEmail()).matches())
            return 1;
        else if (TextUtils.isEmpty(getPassword()) == true)
            return 2;
        else if (getPassword().length() < 6)
            return 3;
        else
            return -1;
    }
}

and this is my test class

public class LoginViewModelTest {

    @Test
    public void isValidUser_Test() {

        User user = new User("[email protected]", "amira123");
        int result = user.isValidUser();
        assertEquals(4, 2 + 2);
    }

}

Can anyone please tell me what the problem is?

EDIT

@Test
    public void isValidUser_happyCase() {

        User user = new User("[email protected]", "amira123");
        int result = user.isValidUser();
        assertEquals(-1, result);
    }

    @Test
    public void isValidUser_emptyEmail() {

        User user = new User("", "amira123");
        int result = user.isValidUser();
        assertEquals(0, result);
    }

    @Test
    public void isValidUser_invalidEmail() {

        User user = new User("aaaaaaa", "amira123");
        int result = user.isValidUser();
        assertEquals(1, result);
    }

    @Test
    public void isValidUser_emptyPassword() {

        User user = new User("[email protected]", "");
        int result = user.isValidUser();
        assertEquals(2, result);
    }

    @Test
    public void isValidUser_invalidPassword() {

        User user = new User("[email protected]", "111");
        int result = user.isValidUser();
        assertEquals(3, result);
    }

1 Answer 1

3

You cannot use classes specific to the Android framework within local JUnit tests (e.g. TextUtils in your case), they are only present as stubs if you enable unitTests.returnDefaultValues = true. From the documentation:

If you run a test that calls an API from the Android SDK that you do not mock, you'll receive an error that says this method is not mocked. That's because the android.jar file used to run unit tests does not contain any actual code (those APIs are provided only by the Android system image on a device).

You've got three options:

  • First is to use the Robolectric testing library, which provides functional versions of Android classes for running in local JUnit tests. This would only need the addition of @RunWith(RobolectricTestRunner.class) at the top of your test.

  • Second is to instead run your tests as Instrumented Unit Tests by placing your test classes under the src/andoidTest folder and running the tests on an actual device or emulator.

  • One last option is to create your own null-safe utility method, as String.isEmpty() can throw a NullPointerException and the Apache StringUtils library is not natively available to Android:


public static boolean isEmpty(@Nullable String in) {
    return in == null || in.isEmpty();
}

I'd advise the first option as you're only using a utility class.

Sign up to request clarification or add additional context in comments.

1 Comment

Ok I will try the first option and get back to you

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.