From 6a0e56c2e379b4fdcdea9c62ed8fd5255be94505 Mon Sep 17 00:00:00 2001 From: Hal Eisen Date: Tue, 16 Jun 2026 23:15:08 -0400 Subject: [PATCH] ADFA-4312 Mock NetworkUtils in CloneRepositoryViewModelTest Surfaced by the nightly Jacoco/SonarQube analyze.yml run after the ADFA-4306 (#1385) fixes landed. Four :app testV8DebugUnitTest cases failed: * cloneRepository fails if destination directory does not exist after clone * cloneRepository failure updates UI with error message * test clone repository with auth is successful * cloneRepository success updates UI state correctly CloneRepositoryViewModel.cloneRepository() calls blankj.utilcode.NetworkUtils.isConnected(), which lazily fires Utils.init() -> android.util.Log.e(). Under the plain JVM test runner Log is not stubbed, so the call throws RuntimeException("Method e in android.util.Log not mocked.") before any assertion runs. ADFA-4306 suggested mockkStatic(Log::class) (mirroring the FileDeleteUtilsTest fix), but for this VM that only patches the transitive symptom and still leaves NetworkUtils.getActiveNetworkInfo() walking into Utils.getApp().getSystemService(...) with no Application context. The more surgical fix is to mock NetworkUtils directly: mockkStatic(NetworkUtils::class) every { NetworkUtils.isConnected() } returns true That matches the semantic intent of these tests (they exercise the clone attempt path, which presumes connectivity) without depending on blankj internals. The existing @After unmockkAll() already covers cleanup. Verified locally by re-running the analyze.yml gradle command (:testing:tooling:assemble :testing:common:assemble sonarqube --info --no-build-cache -x lint --continue): CloneRepositoryViewModelTest now reports tests=9 failures=0 errors=0. --- .../androidide/viewmodel/CloneRepositoryViewModelTest.kt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/src/test/java/com/itsaky/androidide/viewmodel/CloneRepositoryViewModelTest.kt b/app/src/test/java/com/itsaky/androidide/viewmodel/CloneRepositoryViewModelTest.kt index 154ede825a..b3ce6de026 100644 --- a/app/src/test/java/com/itsaky/androidide/viewmodel/CloneRepositoryViewModelTest.kt +++ b/app/src/test/java/com/itsaky/androidide/viewmodel/CloneRepositoryViewModelTest.kt @@ -2,6 +2,7 @@ package com.itsaky.androidide.viewmodel import android.app.Application import androidx.arch.core.executor.testing.InstantTaskExecutorRule +import com.blankj.utilcode.util.NetworkUtils import com.itsaky.androidide.R import com.itsaky.androidide.git.core.GitCredentialsManager import com.itsaky.androidide.git.core.GitRepositoryManager @@ -10,6 +11,7 @@ import io.mockk.coVerify import io.mockk.every import io.mockk.mockk import io.mockk.mockkObject +import io.mockk.mockkStatic import io.mockk.unmockkAll import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.advanceUntilIdle @@ -50,6 +52,13 @@ class CloneRepositoryViewModelTest { @Before fun setup() { + // NetworkUtils.isConnected() transitively triggers blankj Utils.init() -> + // android.util.Log.e(), which throws "not mocked" under plain JVM tests. + // Stub the connectivity check so cloneRepository() proceeds to the + // GitRepositoryManager call these tests are actually exercising. + mockkStatic(NetworkUtils::class) + every { NetworkUtils.isConnected() } returns true + mockkObject(GitRepositoryManager) viewModel = CloneRepositoryViewModel(context, credentialsManager)