From 64d554f926bea66cf0f9221ce7f82788f9fe3f8f Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Sat, 28 Sep 2024 18:33:54 +0200 Subject: [PATCH] =?utf8?q?=F0=9F=91=BD=EF=B8=8F=20Use=20Unsafe=20instead?= =?utf8?q?=20of=20reflection=20to=20set=20private=20field=20for=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This feels like a gigantic step backwards. Additionally, JEP 471 already plans to phase out the method used in here until Java 27 or so, so at some point I will have to fix the underlying issue of the PageMakerInteractionFactory being non-accessible for tests. --- .../net/pterodactylus/sone/test/TestUtils.kt | 27 ++++++++-------------- .../sone/web/page/FreenetTemplatePageTest.kt | 2 +- 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/src/test/kotlin/net/pterodactylus/sone/test/TestUtils.kt b/src/test/kotlin/net/pterodactylus/sone/test/TestUtils.kt index ef23d62..e49663f 100644 --- a/src/test/kotlin/net/pterodactylus/sone/test/TestUtils.kt +++ b/src/test/kotlin/net/pterodactylus/sone/test/TestUtils.kt @@ -1,22 +1,15 @@ package net.pterodactylus.sone.test -import org.junit.rules.* -import java.lang.reflect.* - -private val modifiers = Field::class.java.getDeclaredField("modifiers").apply { - isAccessible = true -} - -fun setField(instance: Any, name: String, value: Any?) { - generateSequence>(instance.javaClass) { it.superclass } - .flatMap { it.declaredFields.asSequence() } - .filter { it.name == name } - .toList() - .forEach { field -> - field.isAccessible = true - modifiers.setInt(field, field.modifiers and Modifier.FINAL.inv()) - field.set(instance, value) - } +import org.junit.rules.ExpectedException +import sun.misc.Unsafe + +inline fun setField(instance: O, name: String, value: Any?) { + val field = O::class.java.getDeclaredField(name) + val unsafe = Unsafe::class.java.getDeclaredField("theUnsafe").apply { + isAccessible = true + }.get(null) as Unsafe + val offset = unsafe.objectFieldOffset(field) + unsafe.putObject(instance, offset, value) } inline fun ExpectedException.expect() = expect(T::class.java) diff --git a/src/test/kotlin/net/pterodactylus/sone/web/page/FreenetTemplatePageTest.kt b/src/test/kotlin/net/pterodactylus/sone/web/page/FreenetTemplatePageTest.kt index 2474d08..e6fd861 100644 --- a/src/test/kotlin/net/pterodactylus/sone/web/page/FreenetTemplatePageTest.kt +++ b/src/test/kotlin/net/pterodactylus/sone/web/page/FreenetTemplatePageTest.kt @@ -131,7 +131,7 @@ class FreenetTemplatePageTest { val request = deepMock() val pageMakerInteractionFactory = deepMock() whenever(pageMakerInteractionFactory.createPageMaker(request.toadletContext, "page title").renderPage()).thenReturn("") - setField(page, "pageMakerInteractionFactory", pageMakerInteractionFactory) + setField(page, "pageMakerInteractionFactory", pageMakerInteractionFactory) val response = page.handleRequest(request, Response(ByteArrayOutputStream())) assertThat(response.statusCode, equalTo(200)) assertThat((response.content as ByteArrayOutputStream).toString(UTF_8.name()), equalTo("")) -- 2.7.4