zwiebl zwiebl - 24 days ago 6
Java Question

Mock testing clarification

I need a clarification about mocking tests. In my particular scenario, I have to test a service, that has the dependency on the connecting module, the connector. Basically what connector does, is that it creates an instance of the service call that has to be made. I will demonstrate on the example.

public DataService(Connector connector) {
this.connector = connector;
}

@Override
public ServiceData getWeatherData(String dataId) throws ServiceCommunicatonException {

try {

return connector.newGetWeatherDataCall().call(
WeatherData.builder().withId(dataId).build());

} catch (Exception e) {
throw new ServiceCommunicatonException(ERR_MSG);
}

}


So the
connector.newGetWeatherDataCall()
returns the instance of the type
WeatherData
.

Now, in order to test the
Service
, I guess I would need to mock the
Connector
. Mocking the
Service
is probably pointless, because then I am not really testing it, right?

I tried mocking the
Connector
with something like this:

@Before
public void setUp() {
connector = mock(Connector.class);
}

@Test
public void getDataTest() {
assertNotNull(service.getData("123"));
}


However, this is obviously wrong, because this gave ma
NullPointerException
because
WeatherDataCall
from this line: return

connector.newGetWeatherDataCall().call(
WeatherData.builder().withId(dataId).build()); was null.


So how should this be properly tested/mocked? It would be great with some code examples.

Answer
@Test
public void getDataTest() {
    WeatherData getWeatherDataResponse = Mockito.mock(WeatherData.class);
    when(connector.newGetWeatherDataCall()).thenReturn(getWeatherDataResponse);
    when(getWeatherDataResponse.call(Matchers.any(Class.class))).thenReturn(new ServiceData());
    assertNotNull(service.getData("123"));
}

Explanation:-

  • You got null because you did not set the expected return value. Actually connector.newGetWeatherDataCall() returns null. This is because you did not use Mockito.when() to return your expected results.
  • Second : In your case, a method on this return value is invoked so connector.newGetWeatherDataCall() should return a mock of WeatherData. And now you will set an expectation for weatherData.call(..) which will be ServiceData type.