1

I am learning the MVP architecture that google uses in their android codelabs. I have set up a simple example. Two input fields and a "+" button to show the addition result. The view is the main activity and I have a presenter that calls a service to add the two input values. The view passes itself to the presenter in the onCreate method and keeps a reference of the presenter as well.

View Interface:

public interface MainView {

    String getFirstInput();

    void showFirstInputError(int resId);

    String getSecondInput();

    void showSecondInputError(int resId);

    void setResultText(int result);
}

Presenter method that is called when the button is pressed:

public void onResultClicked(){
        String firstInput = view.getFirstInput();
        String secondInput = view.getSecondInput();

        if(firstInput.isEmpty()) {
            view.showFirstInputError(R.string.num_input_error);
            return;
        }

        if(secondInput.isEmpty()) {
            view.showSecondInputError(R.string.num_input_error);
            return;
        }

        Service service = new Service();

        int result = service.add(Integer.getInteger(firstInput),
                Integer.getInteger(secondInput));

        view.setResultText(result);

    }

Test:

@Test
    public void shouldPopulateResultWhenButtonIsClicked() throws Exception {
        when(view.getFirstInput()).thenReturn("3");
        when(view.getSecondInput()).thenReturn("3");
        when(service.add(3,3)).thenReturn(6);
        presenter.onResultClicked();
        verify(service).add(3,3);
        verify(view).setResultText(6);
    }

I get an error on the line the service is trying to add the two inputs.

presenter.onResultClicked();
int result = service.add(Integer.getInteger(firstInput),
                    Integer.getInteger(secondInput));

Can somebody please help. Thanks.

java.lang.NullPointerException
    at com.example.ulidder.tdd_mvp_simple.MainPresenter.onResultClicked(MainPresenter.java:29)
    at com.example.ulidder.tdd_mvp_simple.MainPresenterTest.shouldPopulateResultWhenButtonIsClicked(MainPresenterTest.java:46)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    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.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    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.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
    at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
U-L
  • 2,671
  • 8
  • 35
  • 50

1 Answers1

0

It doesn't have anything to do with Android, Mockito or MVP, you're running a jUnit test, it's pure Java.

It's just a NullPointerException, nothing else. Go to line 29 of MainPresenter.java, add a breakpoint and launch the test in debug mode to see which method call is made on a null reference. Extract variables from chained calls if necessary.

I suspect that service.add(...) returns an java.lang.Integer and you're assigning it to an int. If it returns null, the unboxing will get you a NullPointerException at this line. Try assigning the return value to an Integer and debug the value. It may be null.

See this post for more information about unboxing of null values.

Hope this helps.

Community
  • 1
  • 1
Eric Citaire
  • 4,355
  • 1
  • 29
  • 49
  • Thank you. I was using the wrong method to convert String to Integer. It is a java issue as you pointed out. Integer.getInteger() determines the integer value of the system property with the specified name. This was resulting in NPE. I have another quick one - for verify(service).method(), it will only verify that the method() is called on the mock service object right? Not that it is called on any service instance. I think I am right. Want to confirm. If so, I need to pass the service to the presenter to test it is being called. Thank you again ! – U-L Nov 27 '15 at 06:21