2017-03-10 3 views
0

Ich versuche, den Code meiner Presenter Einheit zu testen. Wie Sie unten im Code sehen können, mache ich eine Retrofit-Anfrage und wenn die Antwort erfolgreich ist, rufe ich eine Methode von View.Komponententest Geschäftslogik des Presenters

-Code meines Presenter ich testen wollen:

@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) { 

       } 
      }); 
} 

Und hier ist der Test, den ich schrieb:

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

Das Problem ist, dass ich eine NPE für Zeile bekommen: chatPresenter.onLoadChatrooms(accountId, "0"); Die genaue Fehlermeldung lautet:

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) 

wo line 40 für ChatPresenter ist: .enqueue(new Callback<GetChatroomsServiceResponse>() {

Jeder kann dabei helfen? Ich habe versucht zu überprüfen, ob Presenter null ist und das ist nicht das Problem.

EDIT:

ChatPresenter Konstruktor:

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

und GetChatroomsService:

interface GetChatroomsService { 

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

} 
+0

ist 'getChatroomsService' eine Variable oder haben Sie die Klammern vermisst ?, und wie sieht der Konstruktor von' ChatPresenter' aus? –

+0

@TimothyTruckle Ich habe die Frage mit dem Code von ChatPresenters Konstruktor aktualisiert - auch 'getChatroomsService' ist eine Variable – Mes

+0

Bitte tun Sie sich und Ihren Mitarbeitern einen Gefallen und benennen Sie' getChatroomsService' in etwas um, das den [Java Naming Conventions] (http: //www.oracle.com/technetwork/java/codeconventions-135099.html). –

Antwort

1

Das Problem hierbei ist, dass die verspottet Methode getChatrooms() in getChatroomsService ein null zurückgibt. Der wahrscheinlichste Grund dafür ist, dass die in Ihrem Produktionscode angegebenen Parameter nicht mit den Parametern in Ihrer Mock-Konfiguration übereinstimmen.

Ich selbst benutze den any*() Matcher bei der Konfiguration der Mocks und überprüfe explizit die Parameter, die vom Produktionscode übergeben werden, was mich vor nicht beschreibenden NPEs wie diesem schützt.

@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); 
} 
+0

Wow das war ein guter Fang !! Vielen Dank! Ich beginne gerade mit Komponententests und die Verwendung von 'any *()' ist mir immer noch unklar. Zum Beispiel habe ich versucht, 'anyString()' für accountId und pageNum vars (beim Aufruf von 'onLoadChatrooms()') hinzuzufügen, aber ich bekam einige Fehler, an die ich mich im Moment nicht erinnern kann. – Mes

+1

@Mes: * "Wow, das war ein guter Fang !! Vielen Dank! Ich fange gerade mit Komponententests an" * Ich stieß bei meinem Start auf dieselben Probleme ...; o) - * "Ich habe es vorher versucht adding anyString() [...] aber ich bekam einige Fehler, an die ich mich im Moment nicht erinnern kann. "* Mockito möchte, dass Sie streng sind, entweder Matcher oder (Schein-) Objekte verwenden, die Sie nicht in der Parameterliste mischen können. –