@@ -16,6 +16,7 @@ import io.sentry.protocol.SentryId
1616import io.sentry.protocol.SentryThread
1717import io.sentry.test.ImmediateExecutorService
1818import io.sentry.test.createSentryClientMock
19+ import io.sentry.test.injectForField
1920import io.sentry.util.PlatformTestManipulator
2021import io.sentry.util.thread.IMainThreadChecker
2122import io.sentry.util.thread.MainThreadChecker
@@ -42,6 +43,7 @@ import kotlin.test.AfterTest
4243import kotlin.test.BeforeTest
4344import kotlin.test.Test
4445import kotlin.test.assertEquals
46+ import kotlin.test.assertFails
4547import kotlin.test.assertFalse
4648import kotlin.test.assertIs
4749import kotlin.test.assertNotEquals
@@ -957,12 +959,16 @@ class SentryTest {
957959
958960 @Test
959961 fun `getSpan calls returns root span if globalHubMode is enabled on Android` () {
962+ var sentryOptions: CustomAndroidOptions ? = null
960963 PlatformTestManipulator .pretendIsAndroid(true )
961- Sentry .init ({
964+ Sentry .init (OptionsContainer .create( CustomAndroidOptions :: class .java), {
962965 it.dsn = dsn
963966 it.enableTracing = true
964967 it.sampleRate = 1.0
968+ it.mockName()
969+ sentryOptions = it
965970 }, true )
971+ sentryOptions?.resetName()
966972
967973 val transaction = Sentry .startTransaction(" name" , " op-root" , TransactionOptions ().also { it.isBindToScope = true })
968974 transaction.startChild(" op-child" )
@@ -1174,6 +1180,36 @@ class SentryTest {
11741180 assertTrue(appStartOption.isProfilingEnabled)
11751181 }
11761182
1183+ @Test
1184+ fun `init on Android throws when not using SentryAndroidOptions` () {
1185+ PlatformTestManipulator .pretendIsAndroid(true )
1186+ assertFails(" You are running Android. Please, use SentryAndroid.init." ) {
1187+ Sentry .init {
1188+ it.dsn = dsn
1189+ }
1190+ }
1191+ PlatformTestManipulator .pretendIsAndroid(false )
1192+ }
1193+
1194+ @Test
1195+ fun `init on Android works when using SentryAndroidOptions` () {
1196+ PlatformTestManipulator .pretendIsAndroid(true )
1197+ val options = CustomAndroidOptions ().also {
1198+ it.dsn = dsn
1199+ it.mockName()
1200+ }
1201+ Sentry .init (options)
1202+ options.resetName()
1203+ PlatformTestManipulator .pretendIsAndroid(false )
1204+ }
1205+
1206+ @Test
1207+ fun `init on Java works when not using SentryAndroidOptions` () {
1208+ Sentry .init {
1209+ it.dsn = dsn
1210+ }
1211+ }
1212+
11771213 @Test
11781214 fun `metrics calls scopes getMetrics` () {
11791215 val scopes = mock<IScopes >()
@@ -1260,4 +1296,24 @@ class SentryTest {
12601296 assertFalse(tempFile.exists())
12611297 return tempFile.absolutePath
12621298 }
1299+
1300+ /* *
1301+ * Custom SentryOptions for Android.
1302+ * It needs to call [mockName] to change its name in io.sentry.android.core.SentryAndroidOptions.
1303+ * The name cannot be changed right away, because Sentry.init instantiates the options through reflection.
1304+ * So the name should be changed in option configuration.
1305+ * After the test, it needs to call [resetName] to reset the name back to io.sentry.SentryTest$CustomAndroidOptions,
1306+ * since it's cached internally and would break subsequent tests otherwise.
1307+ */
1308+ private class CustomAndroidOptions : SentryOptions () {
1309+ init {
1310+ resetName()
1311+ }
1312+ fun mockName () {
1313+ javaClass.injectForField(" name" , " io.sentry.android.core.SentryAndroidOptions" )
1314+ }
1315+ fun resetName () {
1316+ javaClass.injectForField(" name" , " io.sentry.SentryTest\$ CustomAndroidOptions" )
1317+ }
1318+ }
12631319}
0 commit comments