android 上的 Mockito 抛出 lang 异常

Mockito on android throwing lang exception

我正在学习 google 在其 android 代码实验室中使用的 MVP 架构。我已经建立了一个简单的例子。两个输入字段和一个“+”按钮来显示加法结果。视图是主要的 activity,我有一个演示者调用一个服务来添加两个输入值。视图在 onCreate 方法中将自身传递给演示者,并保留演示者的引用。

查看界面:

public interface MainView {

    String getFirstInput();

    void showFirstInputError(int resId);

    String getSecondInput();

    void showSecondInputError(int resId);

    void setResultText(int result);
}

按下按钮时调用的 Presenter 方法:

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

我在服务尝试添加两个输入的行上收到错误。

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

有人可以帮忙吗?谢谢。

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.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.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access[=15=]0(ParentRunner.java:58)
    at org.junit.runners.ParentRunner.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)

它与 Android、Mockito 或 MVP 没有任何关系,你是 运行 jUnit 测试,它是纯粹的 Java。

只是一个NullPointerException,没有别的。转到 MainPresenter.java 的第 29 行,添加一个断点并在调试模式下启动测试,以查看在空引用上调用了哪个方法。如有必要,从链式调用中提取变量。

我怀疑 service.add(...) return 是一个 java.lang.Integer 而你将它分配给了一个 int。如果它 return 为 null,则拆箱将在这一行为您提供 NullPointerException。尝试将 return 值分配给 Integer 并调试该值。可能为空。

有关空值拆箱的详细信息,请参阅this post

希望对您有所帮助。