Search code examples
sap-cloud-sdk

How to mock the service generated by Cloud SDK when some methods are final?


We are using sap cloud sdk to consume external OData service. In our Unit Tests we use mockito "RETURNS_DEEP_STUBS" approach to mock the service class generated by Cloud SDK but we get null pointer exception: "java.lang.NullPointerException: Cannot invoke "com.sap.cloud.sdk.datamodel.odatav4.core.NavigationPropertyCollectionQuery.select(com.sap.cloud.sdk.datamodel.odatav4.core.Property[])" because "this.delegateQuery" is null".

when(service.getAllEntities().select(Entities.FIELD_NAME).execute(destination)).thenReturn(List.of(e1, e2));

It seems the root cause is because some methods like "select" and "filter" are defined as final in the generated class by Cloud SDK.

How shall we overcome this? By the way, are there any good and complete documentation or tutorial about how to do unit tests or integration tests when we use Cloud SDK to consume OData API call? Thanks.


Solution

  • If you want to mock the whole helper logic the following way should work:

    BusinessPartner mockedBusinessPartner = mock(BusinessPartner.class);
    DefaultBusinessPartnerService service = spy(new DefaultBusinessPartnerService());
    BusinessPartnerFluentHelper helper = spy(service.getAllBusinessPartner());
    
    doReturn(Collections.singletonList(mockedBusinessPartner)).when(helper).executeRequest(any());
    when(service.getAllBusinessPartner()).thenReturn(helper);
    
    HttpDestination mockDestination = mock(HttpDestination.class);
    List<BusinessPartner> businessPartners = sut.methodToCall(service, mockDestination);
    
    assertThat(businessPartners).containsExactly(mockedBusinessPartner);
    

    So you basically need the service to return a mock BusinessPartnerFluentHelper (or whatever your entity is) and have this helper then return your wanted response.


    For the reason behind the final here: To allow for a safe consumption of varargs parameter we need to use the @SafeVarargs which requires the method to be final.