From a16dcecfeba61a0e695ef72d601d697f0a44c23f Mon Sep 17 00:00:00 2001 From: Yuri Schimke Date: Sun, 14 Jan 2024 10:20:09 +0000 Subject: [PATCH] Allow constructor injection of MockWebServer (#8191) --- android-test/build.gradle.kts | 3 +- .../java/okhttp/android/test/OkHttpTest.kt | 4 +-- mockwebserver-junit5/README.md | 15 +++++++++ .../junit5/internal/MockWebServerExtension.kt | 33 ++++++++++++++----- .../junit5/internal/ExtensionLifecycleTest.kt | 23 ++++++++----- .../ExtensionMultipleInstancesTest.kt | 2 -- .../internal/ExtensionMultipleTestsTest.kt | 4 +-- .../test/kotlin/okhttp3/SuspendCallTest.kt | 3 -- .../okhttp3/dnsoverhttps/DnsOverHttpsTest.kt | 3 -- .../logging/HttpLoggingInterceptorTest.kt | 3 -- .../logging/LoggingEventListenerTest.kt | 3 -- .../sse/internal/EventSourceHttpTest.kt | 3 -- .../sse/internal/EventSourcesHttpTest.kt | 3 -- .../src/test/java/okhttp3/InterceptorTest.kt | 6 ++-- .../okhttp3/internal/tls/ClientAuthTest.kt | 3 -- 15 files changed, 61 insertions(+), 50 deletions(-) diff --git a/android-test/build.gradle.kts b/android-test/build.gradle.kts index 906c22e0f..c2aec16a1 100644 --- a/android-test/build.gradle.kts +++ b/android-test/build.gradle.kts @@ -20,7 +20,8 @@ android { testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunnerArguments += mapOf( "runnerBuilder" to "de.mannodermaus.junit5.AndroidJUnit5Builder", - "notPackage" to "org.bouncycastle" + "notPackage" to "org.bouncycastle", + "configurationParameters" to "junit.jupiter.extensions.autodetection.enabled=true" ) } diff --git a/android-test/src/androidTest/java/okhttp/android/test/OkHttpTest.kt b/android-test/src/androidTest/java/okhttp/android/test/OkHttpTest.kt index eaf37eb90..6d0ec6a0f 100644 --- a/android-test/src/androidTest/java/okhttp/android/test/OkHttpTest.kt +++ b/android-test/src/androidTest/java/okhttp/android/test/OkHttpTest.kt @@ -42,7 +42,6 @@ import javax.net.ssl.TrustManagerFactory import javax.net.ssl.X509TrustManager import mockwebserver3.MockResponse import mockwebserver3.MockWebServer -import mockwebserver3.junit5.internal.MockWebServerExtension import okhttp3.Cache import okhttp3.Call import okhttp3.CertificatePinner @@ -83,14 +82,13 @@ import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith import org.junit.jupiter.api.extension.RegisterExtension import org.opentest4j.TestAbortedException /** * Run with "./gradlew :android-test:connectedCheck -PandroidBuild=true" and make sure ANDROID_SDK_ROOT is set. */ -@ExtendWith(MockWebServerExtension::class) + @Tag("Slow") class OkHttpTest { @Suppress("RedundantVisibilityModifier") diff --git a/mockwebserver-junit5/README.md b/mockwebserver-junit5/README.md index fa5f8a838..8dce14890 100644 --- a/mockwebserver-junit5/README.md +++ b/mockwebserver-junit5/README.md @@ -51,6 +51,21 @@ class MyTest( } ``` +Multiple instances can be obtained by naming additional ones: + +``` +class MyTest( + private val server: MockWebServer, + @MockWebServerInstance("server2") private val server2: MockWebServer, + @MockWebServerInstance("server3") private val server3: MockWebServer +) { + @Test + fun test() { + ... + } +} +``` + Requirements ------------ diff --git a/mockwebserver-junit5/src/main/kotlin/mockwebserver3/junit5/internal/MockWebServerExtension.kt b/mockwebserver-junit5/src/main/kotlin/mockwebserver3/junit5/internal/MockWebServerExtension.kt index 1c9a79caf..b9ece7ec8 100644 --- a/mockwebserver-junit5/src/main/kotlin/mockwebserver3/junit5/internal/MockWebServerExtension.kt +++ b/mockwebserver-junit5/src/main/kotlin/mockwebserver3/junit5/internal/MockWebServerExtension.kt @@ -16,8 +16,10 @@ package mockwebserver3.junit5.internal import java.io.IOException +import java.lang.reflect.Method import java.util.logging.Level import java.util.logging.Logger +import kotlin.jvm.optionals.getOrNull import mockwebserver3.MockWebServer import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement import org.junit.jupiter.api.extension.AfterEachCallback @@ -41,10 +43,25 @@ import org.junit.jupiter.api.extension.ParameterResolver class MockWebServerExtension : BeforeEachCallback, AfterEachCallback, ParameterResolver { private val ExtensionContext.resource: ServersForTest - get() = - getStore(namespace).getOrComputeIfAbsent(this.uniqueId) { + get() { + // For Methods (before/after/test) grab the class store + val store = + if (this.element.getOrNull() is Method) { + val parent = parent.get() + parent.getStore(namespace) + } else { + getStore(namespace) + } + + return store.serversForTest + } + + private val ExtensionContext.Store.serversForTest: ServersForTest + get() { + return getOrComputeIfAbsent(storeKey) { ServersForTest() } as ServersForTest + } private class ServersForTest { private val servers = mutableMapOf() @@ -67,10 +84,11 @@ class MockWebServerExtension : fun shutdownAll() { try { - for (server in servers.values) { + val toClear = servers.values.toList() + servers.clear() + for (server in toClear) { server.shutdown() } - servers.clear() } catch (e: IOException) { logger.log(Level.WARNING, "MockWebServer shutdown failed", e) } @@ -83,9 +101,7 @@ class MockWebServerExtension : parameterContext: ParameterContext, extensionContext: ExtensionContext, ): Boolean { - // Not supported on constructors, or static contexts - return parameterContext.parameter.type === MockWebServer::class.java && - extensionContext.testMethod.isPresent + return parameterContext.parameter.type === MockWebServer::class.java } @Suppress("NewApi") @@ -112,9 +128,10 @@ class MockWebServerExtension : context.resource.shutdownAll() } - companion object { + private companion object { private val logger = Logger.getLogger(MockWebServerExtension::class.java.name) private val namespace = ExtensionContext.Namespace.create(MockWebServerExtension::class.java) private val defaultName = MockWebServerExtension::class.java.simpleName + private val storeKey = "ServersForTest" } } diff --git a/mockwebserver-junit5/src/test/java/mockwebserver3/junit5/internal/ExtensionLifecycleTest.kt b/mockwebserver-junit5/src/test/java/mockwebserver3/junit5/internal/ExtensionLifecycleTest.kt index 62a14c113..b61d063d5 100644 --- a/mockwebserver-junit5/src/test/java/mockwebserver3/junit5/internal/ExtensionLifecycleTest.kt +++ b/mockwebserver-junit5/src/test/java/mockwebserver3/junit5/internal/ExtensionLifecycleTest.kt @@ -17,7 +17,7 @@ package mockwebserver3.junit5.internal import assertk.assertThat import assertk.assertions.isEqualTo -import assertk.assertions.isSameAs +import assertk.assertions.isSameInstanceAs import assertk.assertions.isTrue import mockwebserver3.MockResponse import mockwebserver3.MockWebServer @@ -26,33 +26,38 @@ import okhttp3.Request import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith import org.junit.jupiter.api.extension.RegisterExtension -@ExtendWith(MockWebServerExtension::class) -class ExtensionLifecycleTest { +class ExtensionLifecycleTest(private val constructorServer: MockWebServer) { @RegisterExtension val clientTestRule: OkHttpClientTestRule = OkHttpClientTestRule() - lateinit var setUpServer: MockWebServer - @BeforeEach fun setup(server: MockWebServer) { - this.setUpServer = server + assertThat(constructorServer).isSameInstanceAs(server) assertThat(server.started).isTrue() server.enqueue(MockResponse()) } @AfterEach fun tearDown(server: MockWebServer) { - assertThat(setUpServer).isSameAs(server) + assertThat(constructorServer).isSameInstanceAs(server) assertThat(server.started).isTrue() server.enqueue(MockResponse()) } @Test fun testClient(server: MockWebServer) { - assertThat(setUpServer).isSameAs(server) + assertThat(constructorServer).isSameInstanceAs(server) + assertThat(server.started).isTrue() + clientTestRule.newClient().newCall(Request(server.url("/"))).execute().use { + assertThat(it.code).isEqualTo(200) + } + } + + @Test + fun testClient2(server: MockWebServer) { + assertThat(constructorServer).isSameInstanceAs(server) assertThat(server.started).isTrue() clientTestRule.newClient().newCall(Request(server.url("/"))).execute().use { assertThat(it.code).isEqualTo(200) diff --git a/mockwebserver-junit5/src/test/java/mockwebserver3/junit5/internal/ExtensionMultipleInstancesTest.kt b/mockwebserver-junit5/src/test/java/mockwebserver3/junit5/internal/ExtensionMultipleInstancesTest.kt index 29ac65435..63e14d351 100644 --- a/mockwebserver-junit5/src/test/java/mockwebserver3/junit5/internal/ExtensionMultipleInstancesTest.kt +++ b/mockwebserver-junit5/src/test/java/mockwebserver3/junit5/internal/ExtensionMultipleInstancesTest.kt @@ -23,9 +23,7 @@ import mockwebserver3.MockWebServer import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -@ExtendWith(MockWebServerExtension::class) class ExtensionMultipleInstancesTest { var defaultInstancePort: Int = -1 var instanceAPort: Int = -1 diff --git a/mockwebserver-junit5/src/test/java/mockwebserver3/junit5/internal/ExtensionMultipleTestsTest.kt b/mockwebserver-junit5/src/test/java/mockwebserver3/junit5/internal/ExtensionMultipleTestsTest.kt index a531031f3..516650ea4 100644 --- a/mockwebserver-junit5/src/test/java/mockwebserver3/junit5/internal/ExtensionMultipleTestsTest.kt +++ b/mockwebserver-junit5/src/test/java/mockwebserver3/junit5/internal/ExtensionMultipleTestsTest.kt @@ -19,10 +19,8 @@ import assertk.assertThat import assertk.assertions.isTrue import mockwebserver3.MockWebServer import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -@ExtendWith(MockWebServerExtension::class) -class ExtensionMultipleTestsTest() { +class ExtensionMultipleTestsTest { @Test fun testClient1( defaultInstance: MockWebServer, diff --git a/okhttp-coroutines/src/test/kotlin/okhttp3/SuspendCallTest.kt b/okhttp-coroutines/src/test/kotlin/okhttp3/SuspendCallTest.kt index 883d04038..04a080d03 100644 --- a/okhttp-coroutines/src/test/kotlin/okhttp3/SuspendCallTest.kt +++ b/okhttp-coroutines/src/test/kotlin/okhttp3/SuspendCallTest.kt @@ -35,14 +35,11 @@ import kotlinx.coroutines.withTimeout import mockwebserver3.MockResponse import mockwebserver3.MockWebServer import mockwebserver3.SocketPolicy.DisconnectAfterRequest -import mockwebserver3.junit5.internal.MockWebServerExtension import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith import org.junit.jupiter.api.extension.RegisterExtension import org.junit.jupiter.api.fail -@ExtendWith(MockWebServerExtension::class) class SuspendCallTest { @RegisterExtension val clientTestRule = OkHttpClientTestRule() diff --git a/okhttp-dnsoverhttps/src/test/java/okhttp3/dnsoverhttps/DnsOverHttpsTest.kt b/okhttp-dnsoverhttps/src/test/java/okhttp3/dnsoverhttps/DnsOverHttpsTest.kt index 05b5f1d8f..6cdac3bc1 100644 --- a/okhttp-dnsoverhttps/src/test/java/okhttp3/dnsoverhttps/DnsOverHttpsTest.kt +++ b/okhttp-dnsoverhttps/src/test/java/okhttp3/dnsoverhttps/DnsOverHttpsTest.kt @@ -30,7 +30,6 @@ import java.net.UnknownHostException import java.util.concurrent.TimeUnit import mockwebserver3.MockResponse import mockwebserver3.MockWebServer -import mockwebserver3.junit5.internal.MockWebServerExtension import okhttp3.Cache import okhttp3.Dns import okhttp3.OkHttpClient @@ -44,10 +43,8 @@ import org.junit.jupiter.api.Assertions.fail import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith import org.junit.jupiter.api.extension.RegisterExtension -@ExtendWith(MockWebServerExtension::class) @Tag("Slowish") class DnsOverHttpsTest { @RegisterExtension diff --git a/okhttp-logging-interceptor/src/test/java/okhttp3/logging/HttpLoggingInterceptorTest.kt b/okhttp-logging-interceptor/src/test/java/okhttp3/logging/HttpLoggingInterceptorTest.kt index 9f50930f4..bc93ac55d 100644 --- a/okhttp-logging-interceptor/src/test/java/okhttp3/logging/HttpLoggingInterceptorTest.kt +++ b/okhttp-logging-interceptor/src/test/java/okhttp3/logging/HttpLoggingInterceptorTest.kt @@ -24,7 +24,6 @@ import assertk.assertions.matches import java.net.UnknownHostException import mockwebserver3.MockResponse import mockwebserver3.MockWebServer -import mockwebserver3.junit5.internal.MockWebServerExtension import okhttp3.HttpUrl import okhttp3.Interceptor import okhttp3.MediaType @@ -45,10 +44,8 @@ import org.junit.jupiter.api.Assertions.fail import org.junit.jupiter.api.Assumptions import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith import org.junit.jupiter.api.extension.RegisterExtension -@ExtendWith(MockWebServerExtension::class) class HttpLoggingInterceptorTest { @RegisterExtension val platform = PlatformRule() diff --git a/okhttp-logging-interceptor/src/test/java/okhttp3/logging/LoggingEventListenerTest.kt b/okhttp-logging-interceptor/src/test/java/okhttp3/logging/LoggingEventListenerTest.kt index e519a53cd..91b746351 100644 --- a/okhttp-logging-interceptor/src/test/java/okhttp3/logging/LoggingEventListenerTest.kt +++ b/okhttp-logging-interceptor/src/test/java/okhttp3/logging/LoggingEventListenerTest.kt @@ -23,7 +23,6 @@ import java.util.Arrays import mockwebserver3.MockResponse import mockwebserver3.MockWebServer import mockwebserver3.SocketPolicy.FailHandshake -import mockwebserver3.junit5.internal.MockWebServerExtension import okhttp3.HttpUrl import okhttp3.MediaType.Companion.toMediaType import okhttp3.OkHttpClient @@ -37,10 +36,8 @@ import okhttp3.testing.PlatformRule import org.junit.jupiter.api.Assertions.fail import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith import org.junit.jupiter.api.extension.RegisterExtension -@ExtendWith(MockWebServerExtension::class) @Suppress("ktlint:standard:max-line-length") class LoggingEventListenerTest { @RegisterExtension diff --git a/okhttp-sse/src/test/java/okhttp3/sse/internal/EventSourceHttpTest.kt b/okhttp-sse/src/test/java/okhttp3/sse/internal/EventSourceHttpTest.kt index 6484ecdee..d4fbca2a1 100644 --- a/okhttp-sse/src/test/java/okhttp3/sse/internal/EventSourceHttpTest.kt +++ b/okhttp-sse/src/test/java/okhttp3/sse/internal/EventSourceHttpTest.kt @@ -21,7 +21,6 @@ import assertk.assertions.isEqualTo import java.util.concurrent.TimeUnit import mockwebserver3.MockResponse import mockwebserver3.MockWebServer -import mockwebserver3.junit5.internal.MockWebServerExtension import okhttp3.OkHttpClientTestRule import okhttp3.RecordingEventListener import okhttp3.Request @@ -32,12 +31,10 @@ import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith import org.junit.jupiter.api.extension.RegisterExtension import org.junitpioneer.jupiter.RetryingTest @Tag("Slowish") -@ExtendWith(MockWebServerExtension::class) class EventSourceHttpTest { @RegisterExtension val platform = PlatformRule() diff --git a/okhttp-sse/src/test/java/okhttp3/sse/internal/EventSourcesHttpTest.kt b/okhttp-sse/src/test/java/okhttp3/sse/internal/EventSourcesHttpTest.kt index 3ceb99ea1..4b17e2566 100644 --- a/okhttp-sse/src/test/java/okhttp3/sse/internal/EventSourcesHttpTest.kt +++ b/okhttp-sse/src/test/java/okhttp3/sse/internal/EventSourcesHttpTest.kt @@ -17,7 +17,6 @@ package okhttp3.sse.internal import mockwebserver3.MockResponse import mockwebserver3.MockWebServer -import mockwebserver3.junit5.internal.MockWebServerExtension import okhttp3.OkHttpClientTestRule import okhttp3.Request import okhttp3.sse.EventSources.processResponse @@ -26,11 +25,9 @@ import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith import org.junit.jupiter.api.extension.RegisterExtension @Tag("Slowish") -@ExtendWith(MockWebServerExtension::class) class EventSourcesHttpTest { @RegisterExtension val platform = PlatformRule() diff --git a/okhttp/src/test/java/okhttp3/InterceptorTest.kt b/okhttp/src/test/java/okhttp3/InterceptorTest.kt index 5e9334ca9..336f7df53 100644 --- a/okhttp/src/test/java/okhttp3/InterceptorTest.kt +++ b/okhttp/src/test/java/okhttp3/InterceptorTest.kt @@ -22,7 +22,7 @@ import assertk.assertions.isEqualTo import assertk.assertions.isFalse import assertk.assertions.isNotNull import assertk.assertions.isNull -import assertk.assertions.isSameAs +import assertk.assertions.isSameInstanceAs import assertk.assertions.isTrue import java.io.IOException import java.net.SocketTimeoutException @@ -87,7 +87,7 @@ class InterceptorTest { .addInterceptor(Interceptor { chain: Interceptor.Chain? -> interceptorResponse }) .build() val response = client.newCall(request).execute() - assertThat(response).isSameAs(interceptorResponse) + assertThat(response).isSameInstanceAs(interceptorResponse) } @Test @@ -820,7 +820,7 @@ class InterceptorTest { assertFailsWith { call.execute() } - assertThat(callRef.get()).isSameAs(call) + assertThat(callRef.get()).isSameInstanceAs(call) } private fun uppercase(original: RequestBody?): RequestBody { diff --git a/okhttp/src/test/java/okhttp3/internal/tls/ClientAuthTest.kt b/okhttp/src/test/java/okhttp3/internal/tls/ClientAuthTest.kt index 4249ad08d..12ae6659e 100644 --- a/okhttp/src/test/java/okhttp3/internal/tls/ClientAuthTest.kt +++ b/okhttp/src/test/java/okhttp3/internal/tls/ClientAuthTest.kt @@ -37,7 +37,6 @@ import javax.security.auth.x500.X500Principal import kotlin.test.assertFailsWith import mockwebserver3.MockResponse import mockwebserver3.MockWebServer -import mockwebserver3.junit5.internal.MockWebServerExtension import okhttp3.OkHttpClient import okhttp3.OkHttpClientTestRule import okhttp3.RecordingEventListener @@ -52,12 +51,10 @@ import okhttp3.tls.internal.TlsUtil.newTrustManager import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith import org.junit.jupiter.api.extension.RegisterExtension import org.junitpioneer.jupiter.RetryingTest @Tag("Slowish") -@ExtendWith(MockWebServerExtension::class) class ClientAuthTest { @RegisterExtension val platform = PlatformRule()