Skip to content

Commit

Permalink
Merge pull request #211 from embrace-io/reduce-mocks
Browse files Browse the repository at this point in the history
Reduce mock usage
  • Loading branch information
fractalwrench authored Dec 22, 2023
2 parents dad0ccc + 079673d commit cb57e68
Show file tree
Hide file tree
Showing 11 changed files with 78 additions and 75 deletions.
Original file line number Diff line number Diff line change
@@ -1,28 +1,24 @@
package io.embrace.android.embracesdk

import io.embrace.android.embracesdk.anr.AnrService
import io.embrace.android.embracesdk.capture.crash.EmbraceCrashService
import io.embrace.android.embracesdk.capture.crash.EmbraceUncaughtExceptionHandler
import io.embrace.android.embracesdk.capture.user.UserService
import io.embrace.android.embracesdk.comms.delivery.EmbraceDeliveryService
import io.embrace.android.embracesdk.config.ConfigService
import io.embrace.android.embracesdk.config.local.CrashHandlerLocalConfig
import io.embrace.android.embracesdk.config.local.LocalConfig
import io.embrace.android.embracesdk.config.local.SdkLocalConfig
import io.embrace.android.embracesdk.event.EventService
import io.embrace.android.embracesdk.fakes.FakeAndroidMetadataService
import io.embrace.android.embracesdk.fakes.FakeAnrService
import io.embrace.android.embracesdk.fakes.FakeClock
import io.embrace.android.embracesdk.fakes.FakeConfigService
import io.embrace.android.embracesdk.fakes.FakeEventService
import io.embrace.android.embracesdk.fakes.FakeUserService
import io.embrace.android.embracesdk.fakes.fakeAutoDataCaptureBehavior
import io.embrace.android.embracesdk.gating.EmbraceGatingService
import io.embrace.android.embracesdk.internal.crash.CrashFileMarker
import io.embrace.android.embracesdk.ndk.NdkService
import io.embrace.android.embracesdk.payload.Crash
import io.embrace.android.embracesdk.payload.ExceptionInfo
import io.embrace.android.embracesdk.payload.JsException
import io.embrace.android.embracesdk.payload.ThreadInfo
import io.embrace.android.embracesdk.payload.extensions.CrashFactory
import io.embrace.android.embracesdk.session.SessionService
import io.embrace.android.embracesdk.session.properties.SessionPropertiesService
import io.embrace.android.embracesdk.utils.at
import io.mockk.every
Expand All @@ -33,21 +29,23 @@ import io.mockk.unmockkAll
import io.mockk.verify
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertSame
import org.junit.Before
import org.junit.Test

internal class EmbraceCrashServiceTest {

private lateinit var embraceCrashService: EmbraceCrashService
private lateinit var sessionService: SessionService
private lateinit var sessionService: FakeSessionService
private lateinit var sessionPropertiesService: SessionPropertiesService
private lateinit var metadataService: FakeAndroidMetadataService
private lateinit var deliveryService: EmbraceDeliveryService
private lateinit var userService: UserService
private lateinit var eventService: EventService
private lateinit var anrService: AnrService
private lateinit var ndkService: NdkService
private lateinit var configService: ConfigService
private lateinit var deliveryService: FakeDeliveryService
private lateinit var userService: FakeUserService
private lateinit var eventService: FakeEventService
private lateinit var anrService: FakeAnrService
private lateinit var ndkService: FakeNdkService
private lateinit var configService: FakeConfigService

private lateinit var crash: Crash
private lateinit var localJsException: JsException
Expand All @@ -60,14 +58,14 @@ internal class EmbraceCrashServiceTest {
mockkStatic(Crash::class)
mockkObject(CrashFactory)

sessionService = mockk(relaxed = true)
sessionService = FakeSessionService()
sessionPropertiesService = FakeSessionPropertiesService()
metadataService = FakeAndroidMetadataService()
deliveryService = mockk(relaxUnitFun = true)
userService = mockk(relaxed = true)
eventService = mockk(relaxed = true)
anrService = mockk(relaxUnitFun = true)
ndkService = mockk()
deliveryService = FakeDeliveryService()
userService = FakeUserService()
eventService = FakeEventService()
anrService = FakeAnrService()
ndkService = FakeNdkService()
crashMarker = mockk(relaxUnitFun = true)

localJsException = JsException("jsException", "Error", "Error", "")
Expand Down Expand Up @@ -112,44 +110,43 @@ internal class EmbraceCrashServiceTest {
@Test
fun `test ApiClient and SessionService are called when handleCrash is called with JSException`() {
setupForHandleCrash(true)
every { ndkService.getUnityCrashId() } returns null
embraceCrashService.handleCrash(Thread.currentThread(), testException)

verify { CrashFactory.ofThrowable(testException, localJsException, any()) }
verify { anrService.forceAnrTrackingStopOnCrash() }

verify { deliveryService.sendCrash(any(), true) }
verify { sessionService.handleCrash(crash.crashId) }
assertEquals(1, anrService.forceAnrTrackingStopOnCrashCount)
val lastSentCrash = deliveryService.lastSentCrash
assertNotNull(lastSentCrash)
assertEquals(crash.crashId, sessionService.crashId)

/*
* Verify mainCrashHandled is true after the first execution
* by testing that a second execution of handleCrash wont run anything
*/
embraceCrashService.handleCrash(Thread.currentThread(), testException)
verify(exactly = 1) { anrService.forceAnrTrackingStopOnCrash() }
verify(exactly = 1) { deliveryService.sendCrash(any(), true) }
verify(exactly = 1) { sessionService.handleCrash(crash.crashId) }
assertEquals(1, anrService.forceAnrTrackingStopOnCrashCount)
assertNotNull(deliveryService.lastSentCrash)
assertSame(lastSentCrash, deliveryService.lastSentCrash)
assertEquals(crash.crashId, sessionService.crashId)
}

@Test
fun `test ApiClient and SessionService are called when handleCrash is called with unityId`() {
crash = CrashFactory.ofThrowable(testException, localJsException, "Unity123")
setupForHandleCrash(false)
every { ndkService.getUnityCrashId() } returns "Unity123"
ndkService.lastUnityCrashId = "Unity123"

embraceCrashService.handleCrash(Thread.currentThread(), testException)

verify { CrashFactory.ofThrowable(testException, localJsException, "Unity123") }
verify { anrService.forceAnrTrackingStopOnCrash() }
verify { deliveryService.sendCrash(any(), true) }
verify { sessionService.handleCrash(crash.crashId) }
assertEquals(1, anrService.forceAnrTrackingStopOnCrashCount)
assertNotNull(deliveryService.lastSentCrash)
assertEquals(crash.crashId, sessionService.crashId)
}

@Test
fun `test handleCrash calls mark() method when capture_last_run config is enabled`() {
crash = CrashFactory.ofThrowable(testException, localJsException, "Unity123")
setupForHandleCrash(false)
every { ndkService.getUnityCrashId() } returns null

embraceCrashService.handleCrash(Thread.currentThread(), testException)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import io.embrace.android.embracesdk.payload.WebViewBreadcrumb
internal class FakeBreadcrumbService : BreadcrumbService {

val logViewCalls = mutableListOf<String?>()
var flushCount: Int = 0

override fun getViewBreadcrumbsForSession(start: Long, end: Long): List<ViewBreadcrumb?> =
emptyList()
Expand Down Expand Up @@ -47,6 +48,7 @@ internal class FakeBreadcrumbService : BreadcrumbService {
}

override fun flushBreadcrumbs(): Breadcrumbs {
flushCount++
return Breadcrumbs()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ internal class FakeNdkService : NdkService {
val propUpdates = mutableListOf<Map<String, String>>()

var sessionId: String? = null
var lastUnityCrashId: String? = null

override fun updateSessionId(newSessionId: String) {
sessionId = newSessionId
Expand All @@ -21,7 +22,7 @@ internal class FakeNdkService : NdkService {
}

override fun getUnityCrashId(): String? {
return null
return lastUnityCrashId
}

override fun testCrash(isCpp: Boolean) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import io.embrace.android.embracesdk.session.SessionService

internal class FakeSessionService : SessionService {

var crashId: String? = null

override fun startSession(
coldStart: Boolean,
startType: Session.SessionLifeEventType,
Expand All @@ -21,6 +23,7 @@ internal class FakeSessionService : SessionService {
}

override fun handleCrash(crashId: String) {
this.crashId = crashId
}

override fun endSessionManually(clearUserInfo: Boolean) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import io.embrace.android.embracesdk.config.ConfigService
import io.embrace.android.embracesdk.config.remote.AnrRemoteConfig
import io.embrace.android.embracesdk.fakes.FakeConfigService
import io.embrace.android.embracesdk.fakes.fakeAnrBehavior
import io.embrace.android.embracesdk.session.SessionService
import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
Expand All @@ -22,14 +21,12 @@ internal class NativeThreadSamplerInstallerTest {
private lateinit var sampler: EmbraceNativeThreadSamplerService
private lateinit var configService: ConfigService
private lateinit var anrService: AnrService
private lateinit var sessionService: SessionService
private lateinit var delegate: EmbraceNativeThreadSamplerService.NdkDelegate
private lateinit var cfg: AnrRemoteConfig

@Before
fun setUp() {
anrService = mockk(relaxed = true)
sessionService = mockk(relaxed = true)
delegate = mockk(relaxed = true)
sampler = mockk(relaxed = true)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import android.view.WindowManager
import com.google.common.util.concurrent.MoreExecutors
import io.embrace.android.embracesdk.Embrace
import io.embrace.android.embracesdk.capture.cpu.EmbraceCpuInfoDelegate
import io.embrace.android.embracesdk.comms.delivery.EmbraceCacheService
import io.embrace.android.embracesdk.config.ConfigService
import io.embrace.android.embracesdk.config.local.SdkLocalConfig
import io.embrace.android.embracesdk.fakes.FakeClock
import io.embrace.android.embracesdk.fakes.FakeConfigService
import io.embrace.android.embracesdk.fakes.FakeDeviceArchitecture
import io.embrace.android.embracesdk.fakes.FakePreferenceService
import io.embrace.android.embracesdk.fakes.FakeProcessStateService
Expand Down Expand Up @@ -44,7 +44,6 @@ internal class EmbraceMetadataUnityTest {
private lateinit var configService: ConfigService
private lateinit var preferencesService: FakePreferenceService
private lateinit var processStateService: ProcessStateService
private lateinit var cacheService: EmbraceCacheService
private lateinit var cpuInfoDelegate: EmbraceCpuInfoDelegate
private val deviceArchitecture = FakeDeviceArchitecture()

Expand All @@ -56,11 +55,10 @@ internal class EmbraceMetadataUnityTest {
mockkStatic(Environment::class)

context = mockContext()
buildInfo = mockk()
configService = mockk(relaxed = true)
buildInfo = BuildInfo("1234", "debug", "debug")
configService = FakeConfigService()
preferencesService = FakePreferenceService()
processStateService = FakeProcessStateService()
cacheService = mockk()
cpuInfoDelegate = mockk(relaxed = true)

initContext()
Expand All @@ -85,10 +83,6 @@ internal class EmbraceMetadataUnityTest {
}

private fun initPreferences() {
every { buildInfo.buildId }.returns("1234")
every { buildInfo.buildType }.returns("debug")
every { buildInfo.buildFlavor }.returns("debug")

preferencesService.appVersion = "app-version"
preferencesService.osVersion = "os-version"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import io.embrace.android.embracesdk.payload.AnrInterval
internal class FakeAnrService : AnrService {

var data: List<AnrInterval> = mutableListOf()
var forceAnrTrackingStopOnCrashCount: Int = 0

override fun cleanCollections() {
TODO("Not yet implemented")
Expand All @@ -16,6 +17,7 @@ internal class FakeAnrService : AnrService {
override fun getCapturedData(): List<AnrInterval> = data

override fun forceAnrTrackingStopOnCrash() {
forceAnrTrackingStopOnCrashCount++
}

override fun finishInitialization(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import android.content.Context
import android.content.pm.PackageInfo
import io.embrace.android.embracesdk.Embrace.AppFramework
import io.embrace.android.embracesdk.fakes.FakeAndroidResourcesService
import io.embrace.android.embracesdk.fakes.system.mockApplication
import io.embrace.android.embracesdk.injection.CoreModule
import io.embrace.android.embracesdk.injection.isDebug
import io.embrace.android.embracesdk.internal.serialization.EmbraceSerializer
Expand All @@ -21,7 +22,7 @@ import org.robolectric.RuntimeEnvironment
*/
internal class FakeCoreModule(
override val application: Application =
if (RuntimeEnvironment.getApplication() == null) mockk(relaxed = true) else RuntimeEnvironment.getApplication(),
if (RuntimeEnvironment.getApplication() == null) mockApplication() else RuntimeEnvironment.getApplication(),
override val context: Context =
if (isMockKMock(application)) getMockedContext() else application.applicationContext,
override val appFramework: AppFramework = AppFramework.NATIVE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ import android.os.Build
import android.util.Base64
import com.google.common.util.concurrent.MoreExecutors
import io.embrace.android.embracesdk.Embrace
import io.embrace.android.embracesdk.FakeDeliveryService
import io.embrace.android.embracesdk.ResourceReader
import io.embrace.android.embracesdk.capture.metadata.MetadataService
import io.embrace.android.embracesdk.capture.user.UserService
import io.embrace.android.embracesdk.comms.delivery.EmbraceDeliveryService
import io.embrace.android.embracesdk.config.ConfigService
import io.embrace.android.embracesdk.config.local.LocalConfig
import io.embrace.android.embracesdk.config.local.SdkLocalConfig
import io.embrace.android.embracesdk.fakes.FakeDeviceArchitecture
import io.embrace.android.embracesdk.fakes.FakePreferenceService
import io.embrace.android.embracesdk.fakes.FakeProcessStateService
import io.embrace.android.embracesdk.fakes.FakeUserService
import io.embrace.android.embracesdk.fakes.fakeAutoDataCaptureBehavior
Expand All @@ -27,7 +28,6 @@ import io.embrace.android.embracesdk.internal.utils.Uuid
import io.embrace.android.embracesdk.logging.InternalEmbraceLogger
import io.embrace.android.embracesdk.payload.AppInfo
import io.embrace.android.embracesdk.payload.DeviceInfo
import io.embrace.android.embracesdk.payload.EventMessage
import io.embrace.android.embracesdk.payload.NativeCrashData
import io.embrace.android.embracesdk.payload.NativeCrashMetadata
import io.embrace.android.embracesdk.session.properties.EmbraceSessionProperties
Expand Down Expand Up @@ -60,7 +60,7 @@ internal class EmbraceNdkServiceTest {
private lateinit var configService: ConfigService
private lateinit var activityService: FakeProcessStateService
private lateinit var localConfig: LocalConfig
private lateinit var mockDeliveryService: EmbraceDeliveryService
private lateinit var deliveryService: FakeDeliveryService
private lateinit var userService: UserService
private lateinit var sessionProperties: EmbraceSessionProperties
private lateinit var appFramework: Embrace.AppFramework
Expand All @@ -82,10 +82,10 @@ internal class EmbraceNdkServiceTest {
metadataService = mockk(relaxed = true)
configService = mockk(relaxed = true)
activityService = FakeProcessStateService()
localConfig = mockk(relaxed = true)
mockDeliveryService = mockk()
localConfig = LocalConfig("", false, SdkLocalConfig())
deliveryService = FakeDeliveryService()
userService = FakeUserService()
sessionProperties = mockk(relaxed = true)
sessionProperties = EmbraceSessionProperties(FakePreferenceService(), configService)
appFramework = Embrace.AppFramework.NATIVE
sharedObjectLoader = mockk()
logger = InternalEmbraceLogger()
Expand Down Expand Up @@ -125,7 +125,7 @@ internal class EmbraceNdkServiceTest {
metadataService,
activityService,
configService,
mockDeliveryService,
deliveryService,
userService,
sessionProperties,
appFramework,
Expand Down Expand Up @@ -411,7 +411,7 @@ internal class EmbraceNdkServiceTest {
any() as NativeCrashData
)
}
verify(exactly = 0) { mockDeliveryService.sendMoment(any() as EventMessage) }
assertTrue(deliveryService.sentMoments.isEmpty())
}

@Test
Expand Down Expand Up @@ -521,7 +521,7 @@ internal class EmbraceNdkServiceTest {
verify(exactly = 0) { delegate._getCrashReport(any()) }
verify(exactly = 0) { repository.errorFileForCrash(any()) }
verify(exactly = 0) { repository.mapFileForCrash(any()) }
verify(exactly = 0) { mockDeliveryService.sendMoment(any() as EventMessage) }
assertTrue(deliveryService.sentMoments.isEmpty())
verify(exactly = 0) {
repository.deleteFiles(
any() as File,
Expand All @@ -530,7 +530,7 @@ internal class EmbraceNdkServiceTest {
any() as NativeCrashData
)
}
verify(exactly = 0) { mockDeliveryService.sendMoment(any() as EventMessage) }
assertTrue(deliveryService.sentMoments.isEmpty())
}

@Test
Expand Down
Loading

0 comments on commit cb57e68

Please sign in to comment.