Reputation: 4028
I am trying to test my codebase in the event OkHttpClient throws an IOException
Code under test
try (var response = okHttpClient.newCall(request).execute()) {
return response;
} catch (final IOException e) {
log.error("IO Error from API", e);
throw new ApiException(e.getMessage(), e);
}
Test
@Test
void createCustomer_WhenValidRequestAndIOException_ThenThrowAPIException() throws ZeusServiceException, ZeusClientException {
//Given
final OkHttpClient okHttpClientMock = mock(OkHttpClient.class, RETURNS_DEEP_STUBS);
final OkHttpClient.Builder okHttpBuilderMock = mock(OkHttpClient.Builder.class);
httpClient = new HttpClient(okHttpClientMock, configuration, objectMapper);
//When
when(okHttpClientMock.newBuilder()).thenReturn(okHttpBuilderMock);
when(okHttpBuilderMock.build()).thenReturn(okHttpClientMock);
when(okHttpClientMock.newCall(any())).thenThrow(IOException.class);
final var result = httpClient.createCustomer(request);
assertThatThrownBy(() -> httpClient.createCustomer(request))
.isInstanceOf(ApiException.class)
.hasMessage("IO Error from API");
}
I tried to mock the OkHttpClient
and Builder
class, however Builder is final, and mockito cannot mock it.
In the constructor of the class under test, you are recommended to create a new instance of OkHttpClient by invoking this
this.okHttpClient = okHttpClient.newBuilder().build();
I tried to create a wrapper around OkHttpClient but that didn't work either
public class OkHttpClientWrapper extends OkHttpClient {
private OkHttpClient okHttpClient;
public OkHttpClientWrapper(final OkHttpClient okHttpClient) {
this.okHttpClient = okHttpClient;
}
@Override
public OkHttpClient.Builder newBuilder() {
return new Builder(okHttpClient);
}
}
}
How can I force okhttpclient to throw an IOException?
Upvotes: 10
Views: 2279
Reputation: 4028
In the end the best solution was to leverage OkHttp's MockWebServer
https://github.com/square/okhttp/tree/master/mockwebserver
Using a scenario where MockWebserver unexpectedly terminates the HTTP connection, causes an IOException scenario
@Test
void createCustomer_WhenValidRequestAndServerTerminatesConnection_ThenThrowIOException() throws ZeusServiceException, ZeusClientException {
//Given
final CreateCustomerRequest request = CreateCustomerRequest.builder().build();
//When
mockWebServer.enqueue(new MockResponse()
.setBody(new Buffer().write(new byte[4096]))
.setSocketPolicy(SocketPolicy.DISCONNECT_DURING_RESPONSE_BODY));
assertThatThrownBy(() -> httpClient.createCustomer(request))
.isInstanceOf(IOException.class)
.hasMessage("unexpected end of stream");
}
Note: use of AssertJ library in this test
Upvotes: 9
Reputation: 1530
You have a few options:
Upvotes: 1