Mes
Mes

Reputation: 1691

NPE when calling mock

I have just started with testing and I'm also using MVP pattern in my android apps.

Currently I have a presenter which uses the following android code to test if an email address is valid :

 android.util.Patterns.EMAIL_ADDRESS.matcher(target).matches() 

Since it's not possible to test it with a local JVM unit test I decided to hide it behind an interface :

public interface EmailValidator {

   boolean isValidEmail(CharSequence target);

}

and here's the implementation :

public class EmailValidatorImpl implements EmailValidator {

@Override
public boolean isValidEmail(CharSequence target) {
    if (target == null) {
        return false;
    } else {
        return android.util.Patterns.EMAIL_ADDRESS.matcher(target).matches();
    }
}

}

So now my test code is :

public class SignUpPresenterTest {

@Mock
private SignUpMVP.View view;

@Mock
private EmailValidator validator;

private SignUpPresenter presenter;

private String email = "[email protected]";
private String password = "ABCDabcd";
private String username = "username";

@Before
public void setUp() throws Exception {
    MockitoAnnotations.initMocks(this);

    presenter = new SignUpPresenter(view);
}

@Test
public void onButtonSignUpClicked() throws Exception {
    when(validator.isValidEmail(email))
            .thenReturn(true);

    presenter.onButtonSignUpClicked(email, password, username);

    verify(view).executeSignUpService();
}

}

and now I'm getting a NPE when the code above calls : EmailValidatorImpl.isValidEmail()

java.lang.NullPointerException
at com.example.signup.helpers.EmailValidatorImpl.isValidEmail(EmailValidatorImpl.java:20)
at com.example.signup.SignUpPresenter.showErrors(SignUpPresenter.java:67)
at com.example.signup.SignUpPresenter.onButtonSignUpClicked(SignUpPresenter.java:25)
at com.example.signup.SignUpPresenterTest.onButtonSignUpClicked(SignUpPresenterTest.java:43)

and my questions are : isn't this how I Should use Mockito ? Is there anything I can do to test my code and avoid NPE ?

Upvotes: 1

Views: 228

Answers (2)

MatPag
MatPag

Reputation: 44861

You should try with this, because you need to provide a real implementation of your interface

@InjectMocks
private EmailValidator validator = new EmailValidatorImpl(); 

Upvotes: 2

Juan Cruz Soler
Juan Cruz Soler

Reputation: 8254

That happens because you are mocking the EmailValidator but you are not using that object inside SignUpPresenter.

You should pass the reference in the constructor:

presenter = new SignUpPresenter(view, validator);

or in the method signature:

presenter.onButtonSignUpClicked(email, password, username, validator);


Then you presenter should be something like this:

public class SignUpPresenter {

    private View view;
    private EmailValidator validator;

    public SignUpPresenter(View view, EmailValidator validator) {
        this.view = view;
        this.validator = validator;
    }

    private void onButtonSignUpClicked(String email, String password, String username) {
        //Your code...
        boolean isValid = validator.isValidEmail(email);
    }
}

Upvotes: 2

Related Questions