From 7c2505ab7baa3abe31741c1172777867da0e80d2 Mon Sep 17 00:00:00 2001 From: Gandalf Date: Fri, 12 Jun 2026 12:29:12 +0100 Subject: [PATCH] test: refactor MainScreenViewModel tests to use repository mocks instead of fake context --- .../ui/main/MainScreenViewModelTest.kt | 53 ++++++++++++++----- 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/app/src/test/java/com/example/esp32aldldashboard/ui/main/MainScreenViewModelTest.kt b/app/src/test/java/com/example/esp32aldldashboard/ui/main/MainScreenViewModelTest.kt index d4f1252..9ac286b 100644 --- a/app/src/test/java/com/example/esp32aldldashboard/ui/main/MainScreenViewModelTest.kt +++ b/app/src/test/java/com/example/esp32aldldashboard/ui/main/MainScreenViewModelTest.kt @@ -1,29 +1,49 @@ package com.example.esp32aldldashboard.ui.main -import android.content.Context -import android.content.ContextWrapper import com.example.esp32aldldashboard.bluetooth.ConnectionState +import com.example.esp32aldldashboard.repository.SettingsRepository +import com.example.esp32aldldashboard.repository.TelemetryRepository +import io.mockk.* import junit.framework.TestCase.assertEquals import junit.framework.TestCase.assertFalse import junit.framework.TestCase.assertTrue +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest +import org.junit.Before import org.junit.Test class MainScreenViewModelTest { - private class FakeContext : ContextWrapper(null) { - override fun getApplicationContext(): Context { - return this - } - override fun getSystemService(name: String): Any? { - return null + private val telemetryRepository = mockk(relaxed = true) + private val settingsRepository = mockk(relaxed = true) + private val isCelsiusFlow = MutableStateFlow(false) + + @Before + fun setUp() { + // Clear mocks + clearAllMocks() + + // Stub telemetry repository flows + every { telemetryRepository.connectionState } returns MutableStateFlow(ConnectionState.DISCONNECTED) + every { telemetryRepository.latestFrame } returns MutableStateFlow(null) + every { telemetryRepository.rawHexLog } returns MutableStateFlow(emptyList()) + every { telemetryRepository.errorMessage } returns MutableStateFlow("") + every { telemetryRepository.framesReceived } returns MutableStateFlow(0) + every { telemetryRepository.parseErrors } returns MutableStateFlow(0) + every { telemetryRepository.currentFrameRate } returns MutableStateFlow(0) + + // Stub settings repository + isCelsiusFlow.value = false + every { settingsRepository.isCelsiusFlow } returns isCelsiusFlow + coEvery { settingsRepository.setIsCelsius(any()) } answers { + isCelsiusFlow.value = firstArg() } } @Test fun testInitialStates() = runTest { - val context = FakeContext() - val viewModel = MainScreenViewModel(context) + val viewModel = MainScreenViewModel(telemetryRepository, settingsRepository) assertEquals(ConnectionState.DISCONNECTED, viewModel.connectionState.value) assertEquals(null, viewModel.latestFrame.value) @@ -32,13 +52,22 @@ class MainScreenViewModelTest { @Test fun testToggleTemperatureUnit() = runTest { - val context = FakeContext() - val viewModel = MainScreenViewModel(context) + val viewModel = MainScreenViewModel(telemetryRepository, settingsRepository) + // Wait for stateIn initialization + runCurrent() assertFalse(viewModel.isCelsius.value) + viewModel.toggleTemperatureUnit() + runCurrent() // Wait for viewmodel scope coroutine to execute settingsRepository.setIsCelsius + runCurrent() // Wait for settingsRepository update flow to propagate back through stateIn + assertTrue(viewModel.isCelsius.value) + viewModel.toggleTemperatureUnit() + runCurrent() + runCurrent() + assertFalse(viewModel.isCelsius.value) } }