Reputation: 1691
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
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
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