0

In my android app, I take the input from the edit text when the login button is clicked and pass it to my presenter. The presenter then validates it using the LoginValidator utility class, depending on the result it either continues with the normal login flow or sends a message to the activity notifying that the email or/and password is/are invalid.

In the test class for the LoginValidator I do the following:

public class LoginValidatorTest {

    private static final String INVALID_EMAIL = "ewksd";
    private static final String VALID_EMAIL = "tom.finet@gmail.com";
    private static final String INVALID_PASSWORD = "sjadsaA";
    private static final String VALID_PASSWORD = "Asdfgh1d";

    @Test
    public void shouldValidateInvalidEmail() {
        Assert.assertEquals(LoginValidator.validateEmail(INVALID_EMAIL), false);
    }

    @Test
    public void shouldValidateValidEmail() {
        Assert.assertEquals(LoginValidator.validateEmail(VALID_EMAIL), true);
    }

    @Test
    public void shouldValidateInvalidPassword() {
        Assert.assertEquals(LoginValidator.validatePassword(INVALID_PASSWORD), false);
    }

    @Test
    public void shouldValidateValidPassword() {
        Assert.assertEquals(LoginValidator.validatePassword(VALID_PASSWORD), true);
    }
}

Here is the LoginValidator class which the test calls:

public class LoginValidator {

    /**
     * @param email the email to be validated
     * @return true if the email is valid
     */
    public static boolean validateEmail(String email) {
        return email != null && Patterns.EMAIL_ADDRESS.matcher(email).matches();
    }

    /**
     *
     * @param password the password to be validated
     * @return true if the password is valid
     */
    public static boolean validatePassword(String password) {
        if (password == null)
            return false;
        else if (password.length() < 6)
            return false;
        else if (!password.contains("^[0-9]"))
            return false;
        else if (!password.contains("[A-Z]+"))
            return false;
        return true;
    }
}

When the tests are running these are the results:

enter image description here

enter image description here

enter image description here

enter image description here

How do I fix my code to make all the tests pass?

UPDATE:

Here is what the regex for the password validation looks like:

enter image description here

From further analysis, I have concluded that the code Patterns.EMAIL_ADDRESS is null and hence when calling .matcher(email) on it causes a NullPointerException. Why the hell is Patterns.EMAIL_ADDRESS returning null?

Gastón Saillén
  • 12,319
  • 5
  • 67
  • 77
Tom Finet
  • 487
  • 1
  • 7
  • 21

4 Answers4

0

Not sure about the mail check but you have an error in your password check. Assuming that you want just check if the password contains a number you should change it from:

 public static boolean validatePassword(String password) {
    if (password == null)
        return false;
    else if (password.length() < 6)
        return false;
    else if (!password.matches(".*[0-9]+.*"))
        return false;
    else if (!password.matches(".*[A-Z]+.*"))
        return false;
    return true;
}

The capital also was incorrect as contains does not accept regex. One of the options would be to use matches.

Maciej Kowalski
  • 25,605
  • 12
  • 54
  • 63
0

Try using Mockito and mock LoginValidator as follows :

// If you want to create an instance
LoginValidator loginValidator = mock(LoginValidator.class);

// If you need to access static methods from that class
mock(LoginValidator.class);
Suraj Makhija
  • 1,376
  • 8
  • 16
0
public static boolean validatePassword(String pwd) {
    return pwd != null && pwd.matches("((?=.*\\d)(?=.*[A-Z]).{6,})");
}

"((?=.*\\d)(?=.*[A-Z]).{6,})" is the regex for at least one number, at least one cap, and at least 6 characters.

Eselfar
  • 3,759
  • 3
  • 23
  • 43
  • I have implemented your method above and passed as pwd the string "Aaaaaaaa7". Which has 1 cap, 1 digit and 9 characters, hence should return true. However I still get a return value of false. @Eselfar – Tom Finet May 04 '17 at 15:48
  • I've copied and passed the code I put above and tried with the string "Aaaaaaaa7" you provided and it returns true on my side. Can you please double check that you've the correct regex (as it could have issues with the '\' character). – Eselfar May 04 '17 at 16:15
  • I have updated the question to show my regex expression. @Eselfar – Tom Finet May 04 '17 at 16:25
  • Are you sure your method returns false at that line? Your *validatePassword(...)* method seems to be different than mine. As I said my code works as expected with all your examples. – Eselfar May 04 '17 at 16:33
0

Had this this problem, it's caused by Patterns.EMAIL_ADDRESS.matcher, this is an Android method so you can neither use it in a unit test (it's always null) nor mock it. You can't mock it because Mockito does not mock android classes. A solution would be making your own regex for emails.