单元测试Presenter的业务逻辑

时间:2017-03-10 10:06:13

标签: java android unit-testing

我试图对Presenter的代码进行单元测试。正如您在代码中看到的那样,我正在进行改造请求,如果响应成功,我会调用View中的方法。

我想要测试的演示者代码:

@Override
public void onLoadChatrooms(String accountId, String pageNum) {
    getChatroomsService.getChatrooms(apiToken, createRequestBodyForGetChatroomsRequest(accountId, pageNum))
            .enqueue(new Callback<GetChatroomsServiceResponse>() {
                @Override
                public void onResponse(Call<GetChatroomsServiceResponse> call, Response<GetChatroomsServiceResponse> response) {
                    if (response.isSuccessful()) {
                        view.showData(Arrays.asList(response.body().getChatRoomsArray()));
                    }
                }

                @Override
                public void onFailure(Call<GetChatroomsServiceResponse> call, Throwable t) {

                }
            });
}

这是我写的测试:

@Mock
private ChatMVP.View view;

@Mock
private GetChatroomsService getChatroomsService;

@Mock
private RequestBody requestBody;

@Mock
private Call<GetChatroomsServiceResponse> call;

@Captor
private ArgumentCaptor<Callback<GetChatroomsServiceResponse>> callback;

@Mock
private List<GetChatroomsResponseNestedItem> chatroomsResponseNestedItems;

private String accountId = "14";
private String apiToken = "someToken";

private ChatPresenter chatPresenter;

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

    chatPresenter = new ChatPresenter(view, getChatroomsService, apiToken);

}

@Test
public void onLoadChatrooms() throws Exception {
    when(getChatroomsService.getChatrooms(apiToken, requestBody))
            .thenReturn(call);

    chatPresenter.onLoadChatrooms(accountId, "0");

    verify(call).enqueue(callback.capture());
    callback.getValue().onResponse(call, getResponse());

    verify(view).showData(chatroomsResponseNestedItems);
}

问题在于我获得了NPE行: chatPresenter.onLoadChatrooms(accountId, "0");

确切的错误消息是:

java.lang.NullPointerException
at my.package.main.fragments.chat.ChatPresenter.onLoadChatrooms(ChatPresenter.java:40)
at my.package.main.fragments.chat.ChatPresenterTest.onLoadChatrooms(ChatPresenterTest.java:70)

其中ChatPresenter的line 40为:.enqueue(new Callback<GetChatroomsServiceResponse>() {

任何人都可以提供帮助吗?我试过检查Presenter是否为空,这不是问题所在。

编辑:

ChatPresenter的构造函数:

class ChatPresenter implements ChatMVP.Presenter {

private ChatMVP.View view;
private GetChatroomsService getChatroomsService;
private String apiToken;

@Inject
ChatPresenter(ChatMVP.View view, GetChatroomsService getChatroomsService, @Named("Api-Token") String apiToken) {
    this.view = view;
    this.getChatroomsService = getChatroomsService;
    this.apiToken = apiToken;
}

和GetChatroomsService:

interface GetChatroomsService {

@POST("getchatrooms")
Call<GetChatroomsServiceResponse> getChatrooms(@Query("api_token") String apiToken, @Body RequestBody requestBody);

}

1 个答案:

答案 0 :(得分:1)

这里的问题是getChatrooms()中的模拟方法getChatroomsService会返回null。最可能的原因是生产代码中给出的参数与模拟配置中的参数不匹配。

我自己在配置模拟时使用any*()匹配器,并明确验证生产代码传入的参数,这样可以使我免于像这样的非描述性NPE。

@Test
public void onLoadChatrooms() throws Exception {
    when(getChatroomsService.getChatrooms(anyString(), any(RequestBody.class)))
            .thenReturn(call);

    chatPresenter.onLoadChatrooms(accountId, "0");

    verify(call).enqueue(callback.capture());
    callback.getValue().onResponse(call, getResponse());

    verify(getChatroomsService).getChatrooms(apiToken,requestBody);
    verify(view).showData(chatroomsResponseNestedItems);
}