Null pointer exception when validating email in android - android

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:
How do I fix my code to make all the tests pass?
UPDATE:
Here is what the regex for the password validation looks like:
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?

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);

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.

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.

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.

Related

How to let espresso tests fail for a specific condition

For my espresso tests, I am searching for a way to let all tests fail before they run, if a specific condition is not met. How can I achieve this?
How about creating a jUnit rule to handle that? Specifically the Verifier rule. https://github.com/junit-team/junit4/wiki/rules#verifier-rule
Verifier is a base class for Rules like ErrorCollector, which can turn
otherwise passing test methods into failing tests if a verification check is failed.
private static String sequence;
public static class UsesVerifier {
#Rule
public final Verifier collector = new Verifier() {
#Override
protected void verify() {
sequence += "verify ";
}
};
#Test
public void example() {
sequence += "test ";
}
#Test
public void verifierRunsAfterTest() {
sequence = "";
assertThat(testResult(UsesVerifier.class), isSuccessful());
assertEquals("test verify ", sequence);
}
}
Have you tried System.exit(-1) or System.exit(0) ? One of these should serve your purpose depending on what condition you are trying to check. You can read more about them here.

Null Pointer Exception When Checking If SharedPrefs Equals Null

I am making an Android app that captures a user's e-mail through the displayEmailCaptureFragment() method. If I already captured the user's e-mail, I do not want to prompt the user to enter their e-mail again.
I declare the customerEmailAddress String right after my MainActivity but before the onCreate method:
public class MainActivity extends FragmentActivity implements View.OnClickListener, BillingProcessor.IBillingHandler,
EmailCapturedListener {
private MyPagerAdapter pageAdapter;
private Button mDownloadResumeButton;
private ImageButton mRightArrow, mLeftArrow;
private static final String EMAILKEY = "email_key";
public static final String EDITSKU = "professional_editing_service_1499";
public static final String EMAILSKU = "resume_template_pro_99";
private static final String RBPEMAIL = "rbproeditor#gmail.com";
private static final String RBPPASSWORD = "Redhawks123";
public String customerEmailAddress;
I then have an OnClick() method based on a user's response action within the app. Essentially, I am try to allow for a certain activity after the onClick if the user already entered their e-mail address. If they did not enter their e-mail address, then I prompt them to enter their e-mail and save it to shared preferences. I use a basic if - else statement, however I am still generating a null pointer exception even though I assign the customerEmailAddress string:
#Override
public void onClick(View v) {
int currentPosition = pager.getCurrentItem();
switch (v.getId()) {
case R.id.right_arrow:
pager.setCurrentItem(currentPosition + 1);
break;
case R.id.left_arrow:
pager.setCurrentItem(currentPosition - 1);
break;
case R.id.download_resume_button:
customerEmailAddress = mPrefs.getString(EMAILKEY, null);
if (customerEmailAddress.equals(null)){
displayEmailCaptureFragment();
}
else {
showPurchaseDialog();
}
break;
}
}
Any help is appreciated!
This code is wrong - you can't call equals(...) or any other method on a null object.
...
customerEmailAddress = mPrefs.getString(EMAILKEY, null);
if (customerEmailAddress.equals(null)){
...
Do like this instead:
customerEmailAddress = mPrefs.getString(EMAILKEY, null);
if (customerEmailAddress == null){
...
OR use TextUtils:
customerEmailAddress = mPrefs.getString(EMAILKEY, null);
if (TextUtils.isEmpty(customerEmailAddress)){
...

How to mock permissions for testing in Android?

With Android 6.0 and new permission model, I am checking if the permission exists before performing certain task.
I want to assign these permissions to available and not available for testing purpose. I have a static class to check various permissions depending on the string.
boolean result = ContextCompat.checkSelfPermission(context, name) == PackageManager.PERMISSION_GRANTED;
Can it be achieved using Mockito or Roboelectric?
If you move your permission checker to a collaborator class, you can mock the collaborator. I am not familiar with the Android return types but the solution would look like this:
class PermissionsChecker {
public String checkSelfPermission(context, name) {
return ContextCompat.checkSelfPermission(context, name);
}
}
class YourApp {
private PermissionsChecker permissionsChecker; //need to inject this via setter or constructor
public doSomething() {
boolean result = permissionsChecker.checkSelfPermission(context, name).equals(PackageManager.PERMISSION_GRANTED);
}
}
class YourAppTest {
PermissionsChecker permissionsChecker = mock(PermissionsChecker.class);
#InjectMocks YourApp app = new YourApp();
#Test
public void hasPermissions() {
when(permissionsChecker.checkSelfPermission(...)).thenReturn("NOT GRANTED");
app.something();
//verify you get some error
}
}

espresso test ignores IdlingResouce isIdle() returning false

There is an IdlingResource, e.g. like this
public class IRWatchlistNamesLoaded implements IdlingResource {
private final static String CLASSNAME = "IRWatchlistNamesLoaded";
private ResourceCallback callback;
public IRWatchlistNamesLoaded () {}
#Override
public String getName() {
return getClass().getName();
}
#Override
public boolean isIdleNow() {
if(LMaxApplication.watchlists.getNames() != null && LMaxApplication.watchlists.getNames().size() > 0) {
callback.onTransitionToIdle();
CustomLog.print(CustomLog.UI_TEST, CLASSNAME, "isIdleNow = TRUE. size = " + LMaxApplication.watchlists.getNames().size());
return true;
}
CustomLog.print(CustomLog.UI_TEST, CLASSNAME, "isIdleNow = FALSE. size = " + LMaxApplication.watchlists.getNames().size());
return false;
}
#Override
public void registerIdleTransitionCallback(ResourceCallback resourceCallback) {
this.callback = resourceCallback;
}
}
And the usage is standard - when I need the resource I call
watchlistLoadedIR = new IRWatchlistNamesLoaded();
needToUnregisterWatchlistLoadedIR = true;
Espresso.registerIdlingResources(watchlistLoadedIR);
What I see in logs is that isIdle() returns false (1 or 2 times), my test keeps going and my resource is not loaded properly, so test fails. Also, need to notice that in some other tests this IdlingResource works and espresso really waits for the resource to be idle. The usage is absolutely the same.
Please, maybe somebody has any idea why this could happen?
I don't know if this will help but there is a great way of setting up IdlingResources described here which might help solve your problem. I have a sneaking suspicion that it has to do with the fact that you are instantiating your class within the test, which I don't think is what you want to be doing, since you need to be using the IdlingResources from with an activity, using onView to perform action on different components which would then end up running the class in question.

Android - can you have multiple variable types for single method() parameter?

Can you have two or more variable types for a single method() parameter?
At the moment, you can do:
method(String string, int int, etc...) {
}
What if you wanted to do something like
method(String or int stringint) {
}
can this be done?
I'd do it like this:
private boolean function(String str){
// Do stuff
}
private boolean function(int intStr){
String str = convertToString(intStr);
return function(str);
}
Avoids unnecessary classes, etc.
Just overload the method signature.
public void someMethod(string argument){
}
public void someMethod(int argument){
}
If you have to stick to one single parameter you can use a wrapper, which contains two fiels:
public class MyWrapper
{
String stringValue;
int intValue;
}
public void someMethod(MyWrapper arg)
{
if(arg.stringField != null)
{
// do something with the string
}
/* checking for the default value 0 makes no sense here, since it
might be a value you actually want to pass - The first conditional
statement covers the case you actually only passed a string
*/
else
{
// do something with the int
}
}

Categories

Resources