Migrate DefaultHttpDataSourceTest from Mockito to MockWebServer

PiperOrigin-RevId: 317636681
This commit is contained in:
ibaker 2020-06-22 13:41:13 +01:00 committed by Andrew Lewis
parent 0ff917ad35
commit 8cccbcf4fd
3 changed files with 65 additions and 110 deletions

View File

@ -23,6 +23,7 @@ project.ext {
junitVersion = '4.13-rc-2' junitVersion = '4.13-rc-2'
guavaVersion = '27.1-android' guavaVersion = '27.1-android'
mockitoVersion = '2.25.0' mockitoVersion = '2.25.0'
mockWebServerVersion = '3.12.0'
robolectricVersion = '4.4-SNAPSHOT' robolectricVersion = '4.4-SNAPSHOT'
checkerframeworkVersion = '2.5.0' checkerframeworkVersion = '2.5.0'
jsr305Version = '3.0.2' jsr305Version = '3.0.2'

View File

@ -66,6 +66,7 @@ dependencies {
exclude module: modulePrefix.substring(1) + 'library-core' exclude module: modulePrefix.substring(1) + 'library-core'
} }
testImplementation 'com.google.guava:guava:' + guavaVersion testImplementation 'com.google.guava:guava:' + guavaVersion
testImplementation 'com.squareup.okhttp3:mockwebserver:' + mockWebServerVersion
testImplementation 'org.robolectric:robolectric:' + robolectricVersion testImplementation 'org.robolectric:robolectric:' + robolectricVersion
testImplementation project(modulePrefix + 'testutils') testImplementation project(modulePrefix + 'testutils')
} }

View File

@ -17,23 +17,19 @@
package com.google.android.exoplayer2.upstream; package com.google.android.exoplayer2.upstream;
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.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
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.testutil.TestUtil; import com.google.android.exoplayer2.testutil.TestUtil;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import okhttp3.Headers;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okio.Buffer;
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 DefaultHttpDataSource}. */ /** Unit tests for {@link DefaultHttpDataSource}. */
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
@ -45,86 +41,84 @@ public class DefaultHttpDataSourceTest {
* table below. Values wrapped in '*' are the ones that should be set in the connection request. * table 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 | | |
* | DefaultHttpDataSource | | *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_withSpecifiedRequestParameters_usesCorrectParameters() throws IOException { public void open_withSpecifiedRequestParameters_usesCorrectParameters() throws Exception {
String defaultParameter = "Default"; MockWebServer mockWebServer = new MockWebServer();
String dataSourceInstanceParameter = "DefaultHttpDataSource"; mockWebServer.enqueue(new MockResponse());
String dataSpecParameter = "Dataspec";
HttpDataSource.RequestProperties defaultParameters = new HttpDataSource.RequestProperties(); String propertyFromConstructor = "fromConstructor";
defaultParameters.set("0", defaultParameter); HttpDataSource.RequestProperties constructorProperties = new HttpDataSource.RequestProperties();
defaultParameters.set("1", defaultParameter); constructorProperties.set("0", propertyFromConstructor);
defaultParameters.set("2", defaultParameter); constructorProperties.set("1", propertyFromConstructor);
constructorProperties.set("2", propertyFromConstructor);
constructorProperties.set("4", propertyFromConstructor);
DefaultHttpDataSource dataSource =
new DefaultHttpDataSource(
/* userAgent= */ "testAgent",
/* connectTimeoutMillis= */ 1000,
/* readTimeoutMillis= */ 1000,
/* allowCrossProtocolRedirects= */ false,
constructorProperties);
DefaultHttpDataSource defaultHttpDataSource = String propertyFromSetter = "fromSetter";
Mockito.spy( dataSource.setRequestProperty("1", propertyFromSetter);
new DefaultHttpDataSource( dataSource.setRequestProperty("2", propertyFromSetter);
/* userAgent= */ "testAgent", dataSource.setRequestProperty("3", propertyFromSetter);
/* connectTimeoutMillis= */ 1000, dataSource.setRequestProperty("5", propertyFromSetter);
/* readTimeoutMillis= */ 1000,
/* allowCrossProtocolRedirects= */ false,
defaultParameters));
Map<String, String> sentRequestProperties = new HashMap<>();
HttpURLConnection mockHttpUrlConnection = make200MockHttpUrlConnection(sentRequestProperties);
doReturn(mockHttpUrlConnection).when(defaultHttpDataSource).openConnection(any());
defaultHttpDataSource.setRequestProperty("1", dataSourceInstanceParameter);
defaultHttpDataSource.setRequestProperty("2", dataSourceInstanceParameter);
defaultHttpDataSource.setRequestProperty("3", dataSourceInstanceParameter);
defaultHttpDataSource.setRequestProperty("4", dataSourceInstanceParameter);
String propertyFromDataSpec = "fromDataSpec";
Map<String, String> dataSpecRequestProperties = new HashMap<>(); Map<String, String> dataSpecRequestProperties = new HashMap<>();
dataSpecRequestProperties.put("2", dataSpecParameter); dataSpecRequestProperties.put("2", propertyFromDataSpec);
dataSpecRequestProperties.put("3", dataSpecParameter); dataSpecRequestProperties.put("3", propertyFromDataSpec);
dataSpecRequestProperties.put("5", dataSpecParameter); 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())
.setHttpBody(new byte[] {0, 0, 0, 0})
.setLength(1)
.setKey("key")
.setHttpRequestHeaders(dataSpecRequestProperties) .setHttpRequestHeaders(dataSpecRequestProperties)
.build(); .build();
defaultHttpDataSource.open(dataSpec); dataSource.open(dataSpec);
assertThat(sentRequestProperties.get("0")).isEqualTo(defaultParameter); Headers headers = mockWebServer.takeRequest(10, SECONDS).getHeaders();
assertThat(sentRequestProperties.get("1")).isEqualTo(dataSourceInstanceParameter); assertThat(headers.get("0")).isEqualTo(propertyFromConstructor);
assertThat(sentRequestProperties.get("2")).isEqualTo(dataSpecParameter); assertThat(headers.get("1")).isEqualTo(propertyFromSetter);
assertThat(sentRequestProperties.get("3")).isEqualTo(dataSpecParameter); assertThat(headers.get("2")).isEqualTo(propertyFromDataSpec);
assertThat(sentRequestProperties.get("4")).isEqualTo(dataSourceInstanceParameter); assertThat(headers.get("3")).isEqualTo(propertyFromDataSpec);
assertThat(sentRequestProperties.get("5")).isEqualTo(dataSpecParameter); assertThat(headers.get("4")).isEqualTo(propertyFromDataSpec);
assertThat(headers.get("5")).isEqualTo(propertyFromSetter);
assertThat(headers.get("6")).isEqualTo(propertyFromDataSpec);
} }
@Test @Test
public void open_invalidResponseCode() throws Exception { public void open_invalidResponseCode() throws Exception {
DefaultHttpDataSource defaultHttpDataSource = DefaultHttpDataSource defaultHttpDataSource =
Mockito.spy( new DefaultHttpDataSource(
new DefaultHttpDataSource( /* userAgent= */ "testAgent",
/* userAgent= */ "testAgent", /* connectTimeoutMillis= */ 1000,
/* connectTimeoutMillis= */ 1000, /* readTimeoutMillis= */ 1000,
/* readTimeoutMillis= */ 1000, /* allowCrossProtocolRedirects= */ false,
/* allowCrossProtocolRedirects= */ false, /* defaultRequestProperties= */ null);
/* defaultRequestProperties= */ null));
HttpURLConnection mockHttpUrlConnection = MockWebServer mockWebServer = new MockWebServer();
make404MockHttpUrlConnection(/* responseData= */ TestUtil.createByteArray(1, 2, 3)); mockWebServer.enqueue(
doReturn(mockHttpUrlConnection).when(defaultHttpDataSource).openConnection(any()); new MockResponse()
.setResponseCode(404)
.setBody(new Buffer().write(TestUtil.createByteArray(1, 2, 3))));
DataSpec dataSpec = new DataSpec.Builder().setUri("http://www.google.com").build(); DataSpec dataSpec =
new DataSpec.Builder().setUri(mockWebServer.url("/test-path").toString()).build();
HttpDataSource.InvalidResponseCodeException exception = HttpDataSource.InvalidResponseCodeException exception =
assertThrows( assertThrows(
@ -134,45 +128,4 @@ public class DefaultHttpDataSourceTest {
assertThat(exception.responseCode).isEqualTo(404); assertThat(exception.responseCode).isEqualTo(404);
assertThat(exception.responseBody).isEqualTo(TestUtil.createByteArray(1, 2, 3)); assertThat(exception.responseBody).isEqualTo(TestUtil.createByteArray(1, 2, 3));
} }
/**
* Creates a mock {@link HttpURLConnection} that stores all request parameters inside {@code
* requestProperties}.
*/
private static HttpURLConnection make200MockHttpUrlConnection(
Map<String, String> requestProperties) throws IOException {
HttpURLConnection mockHttpUrlConnection = Mockito.mock(HttpURLConnection.class);
when(mockHttpUrlConnection.usingProxy()).thenReturn(false);
when(mockHttpUrlConnection.getInputStream())
.thenReturn(new ByteArrayInputStream(new byte[128]));
when(mockHttpUrlConnection.getOutputStream()).thenReturn(new ByteArrayOutputStream());
when(mockHttpUrlConnection.getResponseCode()).thenReturn(200);
when(mockHttpUrlConnection.getResponseMessage()).thenReturn("OK");
Mockito.doAnswer(
(invocation) -> {
String key = invocation.getArgument(0);
String value = invocation.getArgument(1);
requestProperties.put(key, value);
return null;
})
.when(mockHttpUrlConnection)
.setRequestProperty(ArgumentMatchers.anyString(), ArgumentMatchers.anyString());
return mockHttpUrlConnection;
}
/** Creates a mock {@link HttpURLConnection} that returns a 404 response code. */
private static HttpURLConnection make404MockHttpUrlConnection(byte[] responseData)
throws IOException {
HttpURLConnection mockHttpUrlConnection = Mockito.mock(HttpURLConnection.class);
when(mockHttpUrlConnection.getOutputStream()).thenReturn(new ByteArrayOutputStream());
when(mockHttpUrlConnection.getErrorStream()).thenReturn(new ByteArrayInputStream(responseData));
when(mockHttpUrlConnection.getResponseCode()).thenReturn(404);
when(mockHttpUrlConnection.getResponseMessage()).thenReturn("NOT FOUND");
return mockHttpUrlConnection;
}
} }