From 7cf1d838ad1292ec5659da9c9d9b829d1baabd31 Mon Sep 17 00:00:00 2001 From: Pritimay Sarkar Date: Fri, 19 Jan 2024 15:12:26 +0530 Subject: [PATCH] add unit tests --- app/build.gradle | 17 +- .../presentation/autodac/AutoDacViewModel.kt | 7 - .../diagnostics/DiagnosticsViewModel.kt | 10 +- .../AssuranceControlsActivityTest.kt | 6 +- .../hpostesting/AutoDacViewModelTest.kt | 106 ++++++------ .../example/hpostesting/DeviceFragmentTest.kt | 82 +++++++++ .../hpostesting/HemocubeViewModelTest.kt | 156 +++--------------- 7 files changed, 175 insertions(+), 209 deletions(-) create mode 100644 app/src/test/java/com/example/hpostesting/DeviceFragmentTest.kt diff --git a/app/build.gradle b/app/build.gradle index 5ba5aa5..e6c1708 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -52,6 +52,11 @@ android { packagingOptions { exclude 'mockito-extensions/org.mockito.plugins.MockMaker' } +// testOptions { +// unitTests { +// includeAndroidResources = true +// } +// } } dependencies { @@ -62,7 +67,7 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'com.google.android.material:material:1.11.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' - implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.7.0' implementation 'androidx.fragment:fragment-ktx:1.6.2' //firebase @@ -91,8 +96,10 @@ dependencies { testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' - androidTestImplementation "androidx.work:work-testing:2.9.0" + testImplementation "androidx.work:work-testing:2.9.0" androidTestImplementation 'androidx.test:core-ktx:1.5.0' + testImplementation 'androidx.fragment:fragment-testing:1.6.2' + testImplementation "org.robolectric:robolectric:4.7" // mockk testImplementation 'io.mockk:mockk:1.10.6' @@ -105,8 +112,8 @@ dependencies { testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.1' - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2" - implementation 'com.opencsv:opencsv:5.5' + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0" + implementation 'com.opencsv:opencsv:5.9' implementation 'com.github.mik3y:usb-serial-for-android:3.5.1' implementation "androidx.fragment:fragment-ktx:1.6.2" @@ -117,7 +124,7 @@ dependencies { // Barcode scanner implementation 'com.journeyapps:zxing-android-embedded:4.3.0' - // Google ML Kit usign play services + // Google ML Kit using play services implementation 'com.google.android.gms:play-services-code-scanner:16.1.0' //Room diff --git a/app/src/main/java/com/example/hpostesting/presentation/autodac/AutoDacViewModel.kt b/app/src/main/java/com/example/hpostesting/presentation/autodac/AutoDacViewModel.kt index 7a03cb3..c4ada03 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/autodac/AutoDacViewModel.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/autodac/AutoDacViewModel.kt @@ -29,11 +29,7 @@ class AutoDacViewModel @Inject constructor( private val sharedPreference: SharedPreferences = context.getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE) - private val _networkStatusLiveData = NetworkStatusLiveData(context) - val allUserData = hemoCubeDao.getAll() val deviceData = MutableLiveData() - val networkStatusLiveData: LiveData - get() = _networkStatusLiveData val fireBaseUpload = MutableLiveData() fun addAutoDacDataToDb(data: DiagnosticsData) { @@ -41,17 +37,14 @@ class AutoDacViewModel @Inject constructor( try { when (val response = repository.addDiagnostics(data)) { is Response.Success -> { - Log.i("Testdb", "Data uploaded to Firestore successfully") fireBaseUpload.postValue("Success") } is Response.Error -> { - Log.e("Testdb", "Error uploading data to Firestore: $response") fireBaseUpload.postValue("Error") } } } catch (e: Exception) { - Log.e("Testdb", "Exception during data upload: ${e.message}") fireBaseUpload.postValue("Error") } } diff --git a/app/src/main/java/com/example/hpostesting/presentation/diagnostics/DiagnosticsViewModel.kt b/app/src/main/java/com/example/hpostesting/presentation/diagnostics/DiagnosticsViewModel.kt index 7a2b7a9..bde77a6 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/diagnostics/DiagnosticsViewModel.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/diagnostics/DiagnosticsViewModel.kt @@ -35,11 +35,7 @@ class DiagnosticsViewModel @Inject constructor( private val sharedPreference: SharedPreferences = context.getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE) - private val _networkStatusLiveData = NetworkStatusLiveData(context) - val allUserData = hemoCubeDao.getAll() val deviceData = MutableLiveData() - val networkStatusLiveData: LiveData - get() = _networkStatusLiveData val fireBaseUpload = MutableLiveData() fun addDiagnosticsDataToDb(data: DiagnosticsData) { @@ -47,19 +43,19 @@ class DiagnosticsViewModel @Inject constructor( try { when (val response = repository.addDiagnostics(data)) { is Response.Success -> { - Log.i("Testdb", "Data uploaded to Firestore successfully") +// Log.i("Testdb", "Data uploaded to Firestore successfully") fireBaseUpload.postValue("Success") } is Response.Error -> { - Log.e("Testdb", "Error uploading data to Firestore: $response") +// Log.e("Testdb", "Error uploading data to Firestore: $response") fireBaseUpload.postValue("Error") } else -> {} } } catch (e: Exception) { - Log.e("Testdb", "Exception during data upload: ${e.message}") +// Log.e("Testdb", "Exception during data upload: ${e.message}") fireBaseUpload.postValue("Error") } } diff --git a/app/src/test/java/com/example/hpostesting/AssuranceControlsActivityTest.kt b/app/src/test/java/com/example/hpostesting/AssuranceControlsActivityTest.kt index c042e2d..bba6b21 100644 --- a/app/src/test/java/com/example/hpostesting/AssuranceControlsActivityTest.kt +++ b/app/src/test/java/com/example/hpostesting/AssuranceControlsActivityTest.kt @@ -13,8 +13,8 @@ import org.mockito.Mock import org.mockito.Mockito import org.mockito.junit.MockitoJUnitRunner -@RunWith(MockitoJUnitRunner::class) -class AssuranceControlsActivityTest { +//@RunWith(MockitoJUnitRunner::class) +//class AssuranceControlsActivityTest { // // @Mock // private lateinit var mockContext: Context @@ -62,4 +62,4 @@ class AssuranceControlsActivityTest { // } // Add more tests as needed to cover different scenarios -} +//} diff --git a/app/src/test/java/com/example/hpostesting/AutoDacViewModelTest.kt b/app/src/test/java/com/example/hpostesting/AutoDacViewModelTest.kt index dff904c..496e18e 100644 --- a/app/src/test/java/com/example/hpostesting/AutoDacViewModelTest.kt +++ b/app/src/test/java/com/example/hpostesting/AutoDacViewModelTest.kt @@ -14,6 +14,7 @@ import com.example.hpostesting.presentation.autodac.AutoDacViewModel import io.mockk.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.delay import kotlinx.coroutines.runBlocking import kotlinx.coroutines.test.TestCoroutineDispatcher import kotlinx.coroutines.test.setMain @@ -23,57 +24,58 @@ import org.junit.Test @ExperimentalCoroutinesApi class AutoDacViewModelTest { -// -// @get:Rule -// val instantTaskExecutorRule = InstantTaskExecutorRule() -// -// private lateinit var viewModel: AutoDacViewModel -// private val hemoCubeDao = mockk() -// private val repository = mockk() -// private val context = mockk() -// private val sharedPreferences = mockk() -// private val networkStatusLiveData = mockk() -// -// @Before -// fun setup() { -// MockKAnnotations.init(this) -// // Mocking the Context and its dependencies -// every { context.applicationContext } returns context -// every { context.getSharedPreferences(any(), any()) } returns sharedPreferences -// every { context.getSystemService(any()) } returns networkStatusLiveData -// -// // Mocking the NetworkStatusLiveData -// every { networkStatusLiveData.observe(any(), any()) } just Runs -// -// every { hemoCubeDao.getAll() } returns mockk() -// every { repository.addDiagnostics(any()) } returns Response.Success(Unit) -// -// viewModel = AutoDacViewModel(hemoCubeDao, repository, context) -// -// Dispatchers.setMain(TestCoroutineDispatcher()) -// } -// -// @Test -// fun `test addAutoDacDataToDb success`() = runBlocking { -// // Given -// val diagnosticsData = mockk() -// -// // When -// viewModel.addAutoDacDataToDb(diagnosticsData) -// -// // Then -// assert(viewModel.fireBaseUpload.value == "Success") -// } -// @Test -// fun `test addAutoDacDataToDb error`() = runBlocking { -// // Given -// every { repository.addDiagnostics(any()) } returns Response.Error(Exception("Test error")) -// -// // When -// viewModel.addAutoDacDataToDb(mockk()) -// -// // Then -// assert(viewModel.fireBaseUpload.value == "Error") -// } + @get:Rule + val instantTaskExecutorRule = InstantTaskExecutorRule() + + private lateinit var viewModel: AutoDacViewModel + private val hemoCubeDao = mockk() + private val repository = mockk() + private val context = mockk() + private val sharedPreferences = mockk() + private val networkStatusLiveData = mockk() + + @Before + fun setup() { + MockKAnnotations.init(this) + // Mocking the Context and its dependencies + every { context.applicationContext } returns context + every { context.getSharedPreferences(any(), any()) } returns sharedPreferences + every { context.getSystemService(any()) } returns networkStatusLiveData + + // Mocking the NetworkStatusLiveData + every { networkStatusLiveData.observe(any(), any()) } just Runs + + every { hemoCubeDao.getAll() } returns mockk() +// every { repository.addDiagnostics(any()) } returns Response.Success(Unit) + + viewModel = AutoDacViewModel(hemoCubeDao, repository, context) + + Dispatchers.setMain(TestCoroutineDispatcher()) + } + + @Test + fun `test addAutoDacDataToDb success`() = runBlocking { + // Given + val diagnosticsData = mockk() + coEvery { repository.addDiagnostics(diagnosticsData) } returns Response.Success("Success") + + // When + viewModel.addAutoDacDataToDb(diagnosticsData) + + // Then + assert(viewModel.fireBaseUpload.value == "Success") + } + + @Test + fun `test addAutoDacDataToDb error`() = runBlocking { + // Given + coEvery { repository.addDiagnostics(any()) } returns Response.Error(Exception("Test error")) + + // When + viewModel.addAutoDacDataToDb(mockk()) + + // Then + assert(viewModel.fireBaseUpload.value == "Error") + } } diff --git a/app/src/test/java/com/example/hpostesting/DeviceFragmentTest.kt b/app/src/test/java/com/example/hpostesting/DeviceFragmentTest.kt new file mode 100644 index 0000000..2720b80 --- /dev/null +++ b/app/src/test/java/com/example/hpostesting/DeviceFragmentTest.kt @@ -0,0 +1,82 @@ +package com.example.hpostesting + +import android.content.Context +import android.content.SharedPreferences +import androidx.fragment.app.testing.FragmentScenario +import androidx.fragment.app.testing.launchFragmentInContainer +import androidx.lifecycle.MutableLiveData +import androidx.test.core.app.ApplicationProvider +import com.example.hpostesting.data.constant.Constants +import com.example.hpostesting.data.constant.HemoCubeCommands +import com.example.hpostesting.presentation.deviceinfo.DeviceActivity +import com.example.hpostesting.presentation.UsbServiceListener +import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel +import com.google.firebase.crashlytics.ktx.crashlytics +import com.google.firebase.ktx.Firebase +import `in`.sminnovations.hpostesting.databinding.FragmentDeviceBinding +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.mockito.Mock +import org.mockito.Mockito.* +import org.mockito.MockitoAnnotations + +class DeviceFragmentTest { +// +// @Mock +// private lateinit var sharedPreferences: SharedPreferences +// +// @Mock +// private lateinit var hemoCubeViewModel: HemoCubeViewModel +// +// private lateinit var scenario: FragmentScenario +// +// @Before +// fun setup() { +// MockitoAnnotations.openMocks(this) +// // Mock the ViewModel and SharedPreferences +// `when`(hemoCubeViewModel.progressBar).thenReturn(MutableLiveData()) +// `when`(hemoCubeViewModel.messages).thenReturn(MutableLiveData()) +// +// `when`(sharedPreferences.getString(Constants.DEVICE_ID, "")).thenReturn("mockedDeviceId") +// +// // Launch the fragment in a test container +// scenario = launchFragmentInContainer(themeResId = R.style.Theme_AppCompat) { +// DeviceFragment().apply { +// deviceViewModel = hemoCubeViewModel +// } +// } +// scenario.onFragment { fragment -> +// fragment.sharedPreferences = sharedPreferences +// } +// } +// +// @After +// fun tearDown() { +// scenario.moveToState(Lifecycle.State.DESTROYED) +// } +// +// @Test +// fun testGetDeviceId() { +// // Mock UsbService and its behavior +// val usbService = (scenario.activity as DeviceActivity).mService +// `when`(usbService.sendAndListenToHemoCube( +// eq(HemoCubeCommands.DEVICE_CONFIGURATION_COMMAND), +// any(UsbServiceListener::class.java) +// )).thenAnswer { +// val listener = it.arguments[1] as UsbServiceListener +// listener.onUsbRead("MockedDeviceId".toByteArray()) +// } +// +// // Trigger the method to be tested +// scenario.onFragment { +// it.getDeviceId() +// } +// +// // Verify that the shared preferences were updated +// verify(sharedPreferences.edit()).putString(Constants.DEVICE_ID, "MockedDeviceId") +// verify(sharedPreferences.edit()).apply() +// } + + // Similar tests can be written for other methods +} diff --git a/app/src/test/java/com/example/hpostesting/HemocubeViewModelTest.kt b/app/src/test/java/com/example/hpostesting/HemocubeViewModelTest.kt index 3135873..79e04e7 100644 --- a/app/src/test/java/com/example/hpostesting/HemocubeViewModelTest.kt +++ b/app/src/test/java/com/example/hpostesting/HemocubeViewModelTest.kt @@ -1,24 +1,18 @@ package com.example.hpostesting import android.content.Context -import android.content.SharedPreferences +import android.os.Build import androidx.arch.core.executor.testing.InstantTaskExecutorRule import androidx.lifecycle.Observer -//import androidx.test.core.app.ApplicationProvider -import com.example.hpostesting.data.dao.HemoCubeBufferDao -import com.example.hpostesting.data.dao.HemoCubeDao -import com.example.hpostesting.data.datasource.LocalFileDataSource -import com.example.hpostesting.data.model.log.UploadLogsResponse +import androidx.work.Configuration +import androidx.work.testing.SynchronousExecutor +import androidx.work.testing.WorkManagerTestInitHelper +import com.example.hpostesting.data.Result import com.example.hpostesting.data.model.login.LoginResponse -import com.example.hpostesting.data.repository.DatabaseRepository import com.example.hpostesting.data.repository.Repository import com.example.hpostesting.domain.LogFileManager -import com.example.hpostesting.presentation.hemocube.HemoCubeFragment import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel -import com.example.hpostesting.presentation.hemocube.HemocubeActivity import com.example.hpostesting.util.TestCoroutineRule -import com.google.common.base.Verify.verify -import `in`.sminnovations.hpostesting.databinding.FragmentHemoCubeReferenceBinding import io.mockk.MockKAnnotations import io.mockk.coEvery import io.mockk.coVerify @@ -26,128 +20,22 @@ import io.mockk.every import io.mockk.impl.annotations.MockK import io.mockk.mockk import io.mockk.verify -import junit.framework.TestCase.assertEquals +import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runBlockingTest import org.junit.After import org.junit.Before import org.junit.Rule import org.junit.Test -import org.mockito.ArgumentMatchers -import org.mockito.ArgumentMatchers.any -import org.mockito.ArgumentMatchers.anyString -import org.mockito.Mock -import org.mockito.Mockito -import org.mockito.Mockito.`when` -import org.mockito.MockitoAnnotations +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config import java.io.File -import com.example.hpostesting.data.Result -import kotlinx.coroutines.ExperimentalCoroutinesApi -import androidx.work.Configuration -//import androidx.work.testing.TestListenableWorkerBuilder - -@ExperimentalCoroutinesApi -class HemocubeViewModelTest { -// @Mock -// private lateinit var mockSharedPreferences: SharedPreferences +//@RunWith(RobolectricTestRunner::class) +//@Config(manifest = Config.NONE) +//@ExperimentalCoroutinesApi +//class HemocubeViewModelTest { // -// @Mock -// private lateinit var mockActivity: HemocubeActivity // Replace with your actual Activity class -// -// @Mock -// private lateinit var mockBinding: FragmentHemoCubeReferenceBinding // Replace with your actual Binding class -// -// @Mock -// private lateinit var mockContext: Context -// -// @Mock -// private lateinit var hemoCubeDaoMock: HemoCubeDao -// -// @Mock -// private lateinit var mockRepository: Repository -// -// @Mock -// private lateinit var mockHemoCubeBufferDao: HemoCubeBufferDao -// -// @Mock -// private lateinit var mockLogFileManager: LogFileManager -// -// @Mock -// private lateinit var mockLocalFileDataSource: LocalFileDataSource -// -// private lateinit var hemoCubeFragment: HemoCubeFragment -// -// private lateinit var hemoCubeViewModel: HemoCubeViewModel -// -// @Before -// fun setUp() { -// MockitoAnnotations.openMocks(this) -// hemoCubeFragment = HemoCubeFragment() -// Mockito.`when`( -// mockSharedPreferences.getString( -// ArgumentMatchers.anyString(), -// ArgumentMatchers.anyString() -// ) -// ).thenReturn("dummy_value") -// hemoCubeViewModel = HemoCubeViewModel(hemoCubeDaoMock, mockHemoCubeBufferDao, mockRepository, mockLogFileManager, mockLocalFileDataSource, mockContext) -// } -// -// @Test -// fun `parseData test`() { -// assertEquals(1, 1) -// } -// -// @Test -// fun `getCurrentDate returns date`() { -//// `when`(hemoCubeViewModel.getCurrentDate()).thenReturn("1705429433") -//// -//// val result = hemoCubeViewModel.getCurrentDate() -//// -//// assertEquals("1705429433", hemoCubeViewModel.getCurrentDate()) -// } -// -// @Test -// fun `extractMiddleString to get device id`() { -// // Arrange -// `when`(mockSharedPreferences.getString(anyString(), anyString())).thenReturn("dummy_value") -// -// // Act -// val deviceId = hemoCubeFragment.extractMiddleString("SNS HPP1-9000 SNE") -// -// // Assert -// assertEquals("HPP1-9000", deviceId) -// } -// -// @Test -// fun `updateDeviceId in shared pref`() { -// // Arrange -// `when`(mockSharedPreferences.getString(anyString(), anyString())).thenReturn("HPP1-0001") -// -// // Act -// val deviceId = mockSharedPreferences.getString(anyString(), anyString()) -// -// // Assert -// assertEquals("HPP1-0001", deviceId) -// } -// -// @Test -// fun `allReadingsComplete check`() { -// // Arrange -// val repeatReadingCount = 1 -// val readingsPerSample = 1 -// -// // Act -// val result = hemoCubeFragment.allReadingsComplete(repeatReadingCount, readingsPerSample) -// -// // Assert -// assertEquals(true, result) -// assertEquals(hemoCubeFragment.allReadingsComplete(0, 1), false) -// } - - - - - // @get:Rule // val instantTaskExecutorRule = InstantTaskExecutorRule() // @@ -172,6 +60,13 @@ class HemocubeViewModelTest { // fun setup() { // MockKAnnotations.init(this) // +// val config = Configuration.Builder() +// .setMinimumLoggingLevel(android.util.Log.DEBUG) +// .setExecutor(SynchronousExecutor()) +// .build() +// +// WorkManagerTestInitHelper.initializeTestWorkManager(context, config) +// // every { context.getSharedPreferences(any(), any()) } returns mockk() // // viewModel = HemoCubeViewModel( @@ -192,15 +87,6 @@ class HemocubeViewModelTest { // // @Test // fun `login() should update LiveData with success`() = coroutineRule.runBlockingTest { -// // Set up WorkManager with TestListenableWorkerBuilder -// val config = Configuration.Builder() -// .setMinimumLoggingLevel(android.util.Log.DEBUG) -// .build() -// -// val context = ApplicationProvider.getApplicationContext() -// -// WorkManagerTestInitHelper.initializeTestWorkManager(context, config) -// // // // Arrange // coEvery { repository.login(any()) } returns Result.Success(mockk()) @@ -255,4 +141,4 @@ class HemocubeViewModelTest { // // Assert // verify { observer.onChanged(response) } // } -} \ No newline at end of file +//} \ No newline at end of file