MockWebServer tests got stuck after updating from 3.9.1 to 3.10.0
See original GitHub issueAfter updating from 3.9.1
to 3.10.0
mockwebserver
tests got stuck.
This is how I configure the HttpClient
(I’m setting up HTTPS
and Certificate Pinning ) 👀
private OkHttpClient configureHttpClient() {
CertificatePinnerFactory factory = new CertificatePinnerFactory();
OkHttpClient.Builder builder = client.newBuilder()
.addInterceptor(new GzipRequestInterceptor())
.retryOnConnectionFailure(true)
.certificatePinner(factory.provideCertificatePinnerFor(environment))
.connectionSpecs(Arrays.asList(ConnectionSpec.MODERN_TLS, ConnectionSpec.COMPATIBLE_TLS));
if (isSocketFactoryUnset(sslSocketFactory, x509TrustManager)) {
builder.sslSocketFactory(sslSocketFactory, x509TrustManager);
}
return builder.build();
}
3.9.1
👇
Feb 27, 2018 9:15:56 PM okhttp3.mockwebserver.MockWebServer$2 execute
INFO: MockWebServer[59072] starting to accept connections
Feb 27, 2018 9:15:57 PM okhttp3.mockwebserver.MockWebServer$3 processOneRequest
INFO: MockWebServer[59072] received request: POST /events/v2?access_token=anyAccessToken HTTP/1.1 and responded: HTTP/1.1 204 OK
3.10.0
👇
Feb 27, 2018 9:12:04 PM okhttp3.mockwebserver.MockWebServer$2 execute
INFO: MockWebServer[59055] starting to accept connections
Feb 27, 2018 9:12:06 PM okhttp3.mockwebserver.MockWebServer$3 processConnection
WARNING: MockWebServer[59055] connection from /127.0.0.1 didn't make a request
Following you can find a failing test 👀
package com.mapbox.android.telemetry;
import android.content.Context;
import org.junit.Test;
import java.net.HttpURLConnection;
import java.util.Arrays;
import java.util.List;
import okhttp3.Callback;
import okhttp3.HttpUrl;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
import okhttp3.internal.tls.SslClient;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
public class Foo {
@Test
public void foo() throws Exception {
MockWebServer server = new MockWebServer();
server.useHttps(SslClient.localhost().socketFactory, false);
server.start();
Context mockedContext = mock(Context.class, RETURNS_DEEP_STUBS);
MapboxTelemetry.applicationContext = mockedContext;
TelemetryClient telemetryClient = obtainATelemetryClient("anyAccessToken", "anyUserAgent", server);
List<Event> mockedEvent = obtainAnEvent();
MockResponse mockResponse = new MockResponse();
mockResponse.setResponseCode(HttpURLConnection.HTTP_NO_CONTENT);
mockResponse.setBody("");
server.enqueue(mockResponse);
Callback mockedCallback = mock(Callback.class);
telemetryClient.sendEvents(mockedEvent, mockedCallback);
RecordedRequest request = server.takeRequest();
assertEquals("/events/v2?access_token=anyAccessToken", request.getPath());
}
TelemetryClient obtainATelemetryClient(String accessToken, String userAgent, MockWebServer server) {
TelemetryClientSettings mockedTelemetryClientSettings = provideDefaultTelemetryClientSettings(server);
Logger mockedLogger = mock(Logger.class);
return new TelemetryClient(accessToken, userAgent, mockedTelemetryClientSettings, mockedLogger);
}
private TelemetryClientSettings provideDefaultTelemetryClientSettings(MockWebServer server) {
HttpUrl localUrl = obtainBaseEndpointUrl(server);
SslClient sslClient = SslClient.localhost();
return new TelemetryClientSettings.Builder()
.baseUrl(localUrl)
.sslSocketFactory(sslClient.socketFactory)
.x509TrustManager(sslClient.trustManager)
.build();
}
private List<Event> obtainAnEvent() {
Event theEvent = new AppUserTurnstile("anySdkIdentifier", "anySdkVersion", false);
return obtainEvents(theEvent);
}
private List<Event> obtainEvents(Event... theEvents) {
return Arrays.asList(theEvents);
}
private HttpUrl obtainBaseEndpointUrl(MockWebServer server) {
return server.url("/");
}
}
☝️ is using https://github.com/mapbox/mapbox-events-android code.
You can check that we only bumped OkHttp version to 3.10.0
👉 https://github.com/mapbox/mapbox-events-android/commit/c92a4acdf684cedc003c769f44a62c345ce596f9 and after that tests got stuck.
Tried many things without luck 😓 Any hints? What did it change that could affect tests in that sense?
Issue Analytics
- State:
- Created 6 years ago
- Comments:11 (5 by maintainers)
Top Results From Across the Web
OkHttp MockWebServer fails to accept connections when ...
As I understand the setUp method happens before each test method, which means that a new instance of the mock server is created...
Read more >3.x Change Log - OkHttp
Fix: Don't create malformed URLs when MockWebServer is reached via an IPv6 address. Fix: Don't crash if the system default authenticator is null....
Read more >Test Spring WebClient with MockWebServer from OkHttp
Write tests for your Spring WebClient usage with OkHttp's MockWebServer and mock HTTP responses to test different scenarios.
Read more >Mockito 3.10.0 API - javadoc.io
The Mockito library enables mock creation, verification and stubbing. This javadoc content is also available on the https://site.mockito.org/ web page.
Read more >The Recommended Way Of Testing HTTP Calls ... - Medium
This testing library is built by the Square Team to easily test how the apps behave when making API calls. A mock web...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Mystery solved! Well partially…
After a thoroughly debug session, @Sefford told me that when he bumped OkHttp version to
3.10.0
, he started gettingSSLPeerUnverifiedException: Hostname localhost not verified
messages in their tests and he fixed it addingto the config of the
OkHttpClient
used in their tests. I wasn’t getting those messages because I’m mocking theCallback
so they weren’t logged.Thanks @Sefford for pointing me in that direction 🙏
It seems that after https://github.com/square/okhttp/pull/3764 changes if you’re using MockWebServer with HTTPS you need to add ☝️ to your tests in order to have them ✅ It’d be great if we could add that to the documentation somehow (if that’s the best solution to follow in these cases).
After adding that config to my tests everything is working again 💃
But now I’m wondering why even when passing in an empty
Callback
implementation (without adding the hostname verifier stub) tests still get stuck. Shouldn’t the exception bubble up and stop the execution of the test if the hostname is not verified? It seems that although theCallback
is fired it’s not sending the notification to the lock properly and it remains opened forever. Does that make sense?Let me know if it’s worth it to open a new issue reporting ☝️ or if you prefer to keep the discussion here.
No action to take on this, other than to be afraid of how mocks + onFailure interact poorly.