Migrate OkHttpDataSourceTest from Mockito to MockWebServer

PiperOrigin-RevId: 317637058
This commit is contained in:
ibaker 2020-06-22 13:45:01 +01:00 committed by Andrew Lewis
parent 8cccbcf4fd
commit a6f79901e7
2 changed files with 53 additions and 97 deletions

View File

@ -37,6 +37,7 @@ dependencies {
compileOnly 'org.checkerframework:checker-qual:' + checkerframeworkVersion compileOnly 'org.checkerframework:checker-qual:' + checkerframeworkVersion
compileOnly 'org.jetbrains.kotlin:kotlin-annotations-jvm:' + kotlinAnnotationsVersion compileOnly 'org.jetbrains.kotlin:kotlin-annotations-jvm:' + kotlinAnnotationsVersion
testImplementation project(modulePrefix + 'testutils') testImplementation project(modulePrefix + 'testutils')
testImplementation 'com.squareup.okhttp3:mockwebserver:' + mockWebServerVersion
testImplementation 'org.robolectric:robolectric:' + robolectricVersion testImplementation 'org.robolectric:robolectric:' + robolectricVersion
// Do not update to 3.13.X or later until minSdkVersion is increased to 21: // Do not update to 3.13.X or later until minSdkVersion is increased to 21:
// https://cashapp.github.io/2019-02-05/okhttp-3-13-requires-android-5 // https://cashapp.github.io/2019-02-05/okhttp-3-13-requires-android-5

View File

@ -17,28 +17,21 @@
package com.google.android.exoplayer2.ext.okhttp; package com.google.android.exoplayer2.ext.okhttp;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertThrows;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.upstream.DataSpec; import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.upstream.HttpDataSource; import com.google.android.exoplayer2.upstream.HttpDataSource;
import java.io.IOException; import com.google.common.base.Charsets;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import okhttp3.Call; import okhttp3.Headers;
import okhttp3.MediaType; import okhttp3.OkHttpClient;
import okhttp3.Protocol; import okhttp3.mockwebserver.MockResponse;
import okhttp3.Request; import okhttp3.mockwebserver.MockWebServer;
import okhttp3.Response;
import okhttp3.ResponseBody;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.ArgumentMatchers;
import org.mockito.Mockito;
/** Unit tests for {@link OkHttpDataSource}. */ /** Unit tests for {@link OkHttpDataSource}. */
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
@ -50,114 +43,76 @@ public class OkHttpDataSourceTest {
* below. Values wrapped in '*' are the ones that should be set in the connection request. * below. Values wrapped in '*' are the ones that should be set in the connection request.
* *
* <pre>{@code * <pre>{@code
* +-----------------------+---+-----+-----+-----+-----+-----+ * +---------------+-----+-----+-----+-----+-----+-----+-----+
* | | Header Key | * | | Header Key |
* +-----------------------+---+-----+-----+-----+-----+-----+ * +---------------+-----+-----+-----+-----+-----+-----+-----+
* | Location | 0 | 1 | 2 | 3 | 4 | 5 | * | Location | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
* +-----------------------+---+-----+-----+-----+-----+-----+ * +---------------+-----+-----+-----+-----+-----+-----+-----+
* | Default |*Y*| Y | Y | | | | * | Constructor | *Y* | Y | Y | | Y | | |
* | OkHttpDataSource | | *Y* | Y | Y | *Y* | | * | Setter | | *Y* | Y | Y | | *Y* | |
* | DataSpec | | | *Y* | *Y* | | *Y* | * | DataSpec | | | *Y* | *Y* | *Y* | | *Y* |
* +-----------------------+---+-----+-----+-----+-----+-----+ * +---------------+-----+-----+-----+-----+-----+-----+-----+
* }</pre> * }</pre>
*/ */
@Test @Test
public void open_setsCorrectHeaders() throws HttpDataSource.HttpDataSourceException { public void open_setsCorrectHeaders() throws Exception {
String defaultValue = "Default"; MockWebServer mockWebServer = new MockWebServer();
String okHttpDataSourceValue = "OkHttpDataSource"; mockWebServer.enqueue(new MockResponse());
String dataSpecValue = "DataSpec";
// 1. Default properties on OkHttpDataSource String propertyFromConstructor = "fromConstructor";
HttpDataSource.RequestProperties defaultRequestProperties = HttpDataSource.RequestProperties constructorProperties = new HttpDataSource.RequestProperties();
new HttpDataSource.RequestProperties(); constructorProperties.set("0", propertyFromConstructor);
defaultRequestProperties.set("0", defaultValue); constructorProperties.set("1", propertyFromConstructor);
defaultRequestProperties.set("1", defaultValue); constructorProperties.set("2", propertyFromConstructor);
defaultRequestProperties.set("2", defaultValue); constructorProperties.set("4", propertyFromConstructor);
OkHttpDataSource dataSource =
Call.Factory mockCallFactory = mock(Call.Factory.class);
OkHttpDataSource okHttpDataSource =
new OkHttpDataSource( new OkHttpDataSource(
mockCallFactory, "testAgent", /* cacheControl= */ null, defaultRequestProperties); new OkHttpClient(), "testAgent", /* cacheControl= */ null, constructorProperties);
// 2. Additional properties set with setRequestProperty(). String propertyFromSetter = "fromSetter";
okHttpDataSource.setRequestProperty("1", okHttpDataSourceValue); dataSource.setRequestProperty("1", propertyFromSetter);
okHttpDataSource.setRequestProperty("2", okHttpDataSourceValue); dataSource.setRequestProperty("2", propertyFromSetter);
okHttpDataSource.setRequestProperty("3", okHttpDataSourceValue); dataSource.setRequestProperty("3", propertyFromSetter);
okHttpDataSource.setRequestProperty("4", okHttpDataSourceValue); dataSource.setRequestProperty("5", propertyFromSetter);
// 3. DataSpec properties String propertyFromDataSpec = "fromDataSpec";
Map<String, String> dataSpecRequestProperties = new HashMap<>(); Map<String, String> dataSpecRequestProperties = new HashMap<>();
dataSpecRequestProperties.put("2", dataSpecValue); dataSpecRequestProperties.put("2", propertyFromDataSpec);
dataSpecRequestProperties.put("3", dataSpecValue); dataSpecRequestProperties.put("3", propertyFromDataSpec);
dataSpecRequestProperties.put("5", dataSpecValue); dataSpecRequestProperties.put("4", propertyFromDataSpec);
dataSpecRequestProperties.put("6", propertyFromDataSpec);
DataSpec dataSpec = DataSpec dataSpec =
new DataSpec.Builder() new DataSpec.Builder()
.setUri("http://www.google.com") .setUri(mockWebServer.url("/test-path").toString())
.setPosition(1000)
.setLength(5000)
.setHttpRequestHeaders(dataSpecRequestProperties) .setHttpRequestHeaders(dataSpecRequestProperties)
.build(); .build();
Mockito.doAnswer( dataSource.open(dataSpec);
invocation -> {
Request request = invocation.getArgument(0);
assertThat(request.header("0")).isEqualTo(defaultValue);
assertThat(request.header("1")).isEqualTo(okHttpDataSourceValue);
assertThat(request.header("2")).isEqualTo(dataSpecValue);
assertThat(request.header("3")).isEqualTo(dataSpecValue);
assertThat(request.header("4")).isEqualTo(okHttpDataSourceValue);
assertThat(request.header("5")).isEqualTo(dataSpecValue);
// return a Call whose .execute() will return a mock Response Headers headers = mockWebServer.takeRequest(10, SECONDS).getHeaders();
Call returnValue = mock(Call.class); assertThat(headers.get("0")).isEqualTo(propertyFromConstructor);
doReturn( assertThat(headers.get("1")).isEqualTo(propertyFromSetter);
new Response.Builder() assertThat(headers.get("2")).isEqualTo(propertyFromDataSpec);
.request(request) assertThat(headers.get("3")).isEqualTo(propertyFromDataSpec);
.protocol(Protocol.HTTP_1_1) assertThat(headers.get("4")).isEqualTo(propertyFromDataSpec);
.code(200) assertThat(headers.get("5")).isEqualTo(propertyFromSetter);
.message("OK") assertThat(headers.get("6")).isEqualTo(propertyFromDataSpec);
.body(ResponseBody.create(MediaType.parse("text/plain"), ""))
.build())
.when(returnValue)
.execute();
return returnValue;
})
.when(mockCallFactory)
.newCall(ArgumentMatchers.any());
okHttpDataSource.open(dataSpec);
} }
@Test @Test
public void open_invalidResponseCode() throws Exception { public void open_invalidResponseCode() throws Exception {
Call.Factory callFactory = MockWebServer mockWebServer = new MockWebServer();
request -> { mockWebServer.enqueue(new MockResponse().setResponseCode(404).setBody("failure msg"));
Call mockCall = mock(Call.class);
try {
when(mockCall.execute())
.thenReturn(
new Response.Builder()
.request(request)
.protocol(Protocol.HTTP_1_1)
.code(404)
.message("NOT FOUND")
.body(ResponseBody.create(MediaType.parse("text/plain"), "failure msg"))
.build());
} catch (IOException e) {
throw new AssertionError(e);
}
return mockCall;
};
OkHttpDataSource okHttpDataSource = OkHttpDataSource okHttpDataSource =
new OkHttpDataSource( new OkHttpDataSource(
callFactory, new OkHttpClient(),
"testAgent", "testAgent",
/* cacheControl= */ null, /* cacheControl= */ null,
/* defaultRequestProperties= */ null); /* defaultRequestProperties= */ null);
DataSpec dataSpec =
DataSpec dataSpec = new DataSpec.Builder().setUri("http://www.google.com").build(); new DataSpec.Builder().setUri(mockWebServer.url("/test-path").toString()).build();
HttpDataSource.InvalidResponseCodeException exception = HttpDataSource.InvalidResponseCodeException exception =
assertThrows( assertThrows(
@ -165,6 +120,6 @@ public class OkHttpDataSourceTest {
() -> okHttpDataSource.open(dataSpec)); () -> okHttpDataSource.open(dataSpec));
assertThat(exception.responseCode).isEqualTo(404); assertThat(exception.responseCode).isEqualTo(404);
assertThat(exception.responseBody).isEqualTo("failure msg".getBytes(C.UTF8_NAME)); assertThat(exception.responseBody).isEqualTo("failure msg".getBytes(Charsets.UTF_8));
} }
} }