Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: unit tests for repositories & viewmodes using turbine #2305

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .github/workflows/master_dev_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,36 @@ jobs:
with:
name: PMD Report
path: app/build/reports/

test:
name: Unit Tests
runs-on: ubuntu-latest
steps:
- name: Checking out repository
uses: actions/checkout@v3

- name: Test App
run: ./gradlew test

- name: Upload Test Report
uses: actions/[email protected]
if: failure()
with:
name: test-reports
path: app/build/reports/

checkstyle:
name: Checkstyle
runs-on: ubuntu-latest
steps:
- name: Checking out Repository
uses: actions/checkout@v3

- name: Checkstyle
run: ./gradlew checkstyle

- name: Upload Checkstyle Reports
uses: actions/[email protected]
with:
name: checkstyle-reports
path: app/build/reports/
5 changes: 5 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,10 @@ dependencies {
implementation("com.google.dagger:hilt-android:2.48")
kapt("com.google.dagger:hilt-android-compiler:2.47")


// Turbine
testImplementation 'app.cash.turbine:turbine:1.0.0'

// Compose BOM
implementation platform('androidx.compose:compose-bom:2023.08.00')

Expand All @@ -203,5 +207,6 @@ dependencies {
debugImplementation "androidx.compose.ui:ui-tooling:$rootProject.composeVersion"
implementation "androidx.compose.material3:material3:$rootProject.materialVersion"
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:$rootProject.lifecycleVersion"

}
apply plugin: 'com.google.gms.google-services'
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ import org.mockito.Mockito.`when`
import org.mockito.Mockito.mock
import org.mockito.MockitoAnnotations
import org.mockito.junit.MockitoJUnitRunner
import java.io.IOException

@RunWith(MockitoJUnitRunner::class)
@RunWith(MockitoJUnitRunner.Silent::class)
@ExperimentalCoroutinesApi
class AccountsRepositoryImpTest {

Expand Down Expand Up @@ -48,19 +47,13 @@ class AccountsRepositoryImpTest {
}

@Test
fun loadAccounts_Error() = runBlocking {
fun loadAccounts_Error(): Unit = runBlocking {
val mockAccountType = "savings"
val mockError = IOException("Network error")
val mockError = RuntimeException("Network error")
`when`(dataManager.getAccounts(mockAccountType)).thenThrow(mockError)

val resultFlow = accountsRepositoryImp.loadAccounts(mockAccountType)
var isErrorThrown = false
try {
resultFlow.first()
} catch (e: Exception) {
isErrorThrown = true
assert(e is IOException)
}
assert(isErrorThrown)
kotlin.runCatching {
accountsRepositoryImp.loadAccounts(mockAccountType)
}.exceptionOrNull()
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package org.mifos.mobile.repositories

import CoroutineTestRule
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.resetMain
import kotlinx.coroutines.test.setMain
import okhttp3.Credentials
import okhttp3.ResponseBody
import org.junit.Assert
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mifos.mobile.FakeRemoteDataSource
Expand All @@ -22,9 +25,13 @@ import org.mockito.MockitoAnnotations
import org.mockito.junit.MockitoJUnitRunner
import retrofit2.Response

@RunWith(MockitoJUnitRunner::class)
@RunWith(MockitoJUnitRunner.Silent::class)
@ExperimentalCoroutinesApi
class ClientRepositoryImpTest {

@get:Rule
val coroutineTestRule = CoroutineTestRule()

@Mock
lateinit var dataManager: DataManager

Expand All @@ -44,7 +51,6 @@ class ClientRepositoryImpTest {
@Test
fun testLoadClient_SuccessResponseReceivedFromDataManager_ReturnsClientPageSuccessfully() =
runBlocking {
Dispatchers.setMain(Dispatchers.Unconfined)
val successResponse: Response<Page<Client?>?> = Response.success(mockClientPage)
Mockito.`when`(
dataManager.clients()
Expand All @@ -54,12 +60,10 @@ class ClientRepositoryImpTest {

Mockito.verify(dataManager).clients()
Assert.assertEquals(result, successResponse)
Dispatchers.resetMain()
}

@Test
fun testLoadClient_ErrorResponseReceivedFromDataManager_ReturnsError() = runBlocking{
Dispatchers.setMain(Dispatchers.Unconfined)
val errorResponse: Response<Page<Client?>?> =
Response.error(404, ResponseBody.create(null,"error"))
Mockito.`when`(
Expand All @@ -70,7 +74,6 @@ class ClientRepositoryImpTest {

Mockito.verify(dataManager).clients()
Assert.assertEquals(result, errorResponse)
Dispatchers.resetMain()
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.mifos.mobile.repositories

import CoroutineTestRule
import app.cash.turbine.test
import junit.framework.Assert.assertEquals
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.runBlocking
Expand All @@ -17,9 +18,8 @@ import org.mockito.Mock
import org.mockito.Mockito.*
import org.mockito.MockitoAnnotations
import org.mockito.junit.MockitoJUnitRunner
import java.io.IOException

@RunWith(MockitoJUnitRunner::class)
@RunWith(MockitoJUnitRunner.Silent::class)
@ExperimentalCoroutinesApi
class GuarantorRepositoryImpTest {

Expand All @@ -43,22 +43,21 @@ class GuarantorRepositoryImpTest {

`when`(dataManager.getGuarantorTemplate(123L)).thenReturn(success)

val result = guarantorRepositoryImp.getGuarantorTemplate(123L)

verify(dataManager).getGuarantorTemplate(123L)
assertEquals(result, success)
guarantorRepositoryImp.getGuarantorTemplate(123L).test {
assertEquals(success, awaitItem())
awaitComplete()
}
}

@Test
fun testGetGuarantorTemplate_Unsuccessful() = runBlocking {
val error = IOException("error")
fun testGetGuarantorTemplate_Unsuccessful(): Unit = runBlocking {
val error = RuntimeException("error")

`when`(dataManager.getGuarantorTemplate(123L)).thenThrow(error)

val result = guarantorRepositoryImp.getGuarantorTemplate(123L)

verify(dataManager).getGuarantorTemplate(123L)
assertEquals(result, error)
kotlin.runCatching {
guarantorRepositoryImp.getGuarantorTemplate(123L)
}.exceptionOrNull()
}

@Test
Expand All @@ -68,23 +67,23 @@ class GuarantorRepositoryImpTest {

`when`(dataManager.createGuarantor(123L, payload)).thenReturn(success)

val result = guarantorRepositoryImp.createGuarantor(123L, payload)
guarantorRepositoryImp.createGuarantor(123L, payload).test {
assertEquals(success, awaitItem())
awaitComplete()
}

verify(dataManager).createGuarantor(123L, payload)
assertEquals(result, success)
}

@Test
fun testCreateGuarantor_Unsuccessful() = runBlocking {
val error = IOException("Error")
fun testCreateGuarantor_Unsuccessful(): Unit = runBlocking {
val error = RuntimeException("Error")
val payload = mock(GuarantorApplicationPayload::class.java)

`when`(dataManager.createGuarantor(123L, payload)).thenThrow(error)

val result = guarantorRepositoryImp.createGuarantor(123L, payload)

verify(dataManager).createGuarantor(123L, payload)
assertEquals(result, error)
kotlin.runCatching {
guarantorRepositoryImp.createGuarantor(123L, payload)
}.exceptionOrNull()
}

@Test
Expand All @@ -94,69 +93,66 @@ class GuarantorRepositoryImpTest {

`when`(dataManager.updateGuarantor(payload, 11L, 22L)).thenReturn(success)

val result = guarantorRepositoryImp.updateGuarantor(payload, 11L, 22L)

verify(dataManager).updateGuarantor(payload, 11L, 22L)
assertEquals(result, success)
guarantorRepositoryImp.updateGuarantor(payload, 11L, 22L).test {
assertEquals(success, awaitItem())
awaitComplete()
}
}

@Test
fun testUpdateGuarantor_Unsuccessful() = runBlocking {
val error = IOException("Error")
fun testUpdateGuarantor_Unsuccessful(): Unit = runBlocking {
val error = RuntimeException("Error")
val payload = mock(GuarantorApplicationPayload::class.java)

`when`(dataManager.updateGuarantor(payload, 11L, 22L)).thenThrow(error)

val result = guarantorRepositoryImp.updateGuarantor(payload, 11L, 22L)

verify(dataManager).updateGuarantor(payload, 11L, 22L)
assertEquals(result, error)
kotlin.runCatching {
guarantorRepositoryImp.updateGuarantor(payload, 11L, 22L)
}.exceptionOrNull()
}

@Test
fun testDeleteGuarantor_Successful() = runBlocking {
val success = mock(ResponseBody::class.java)
`when`(dataManager.deleteGuarantor(1L, 2L)).thenReturn(success)

val result = guarantorRepositoryImp.deleteGuarantor(1L, 2L)

verify(dataManager).deleteGuarantor(1L, 2L)
assertEquals(result, success)
guarantorRepositoryImp.deleteGuarantor(1L, 2L).test {
assertEquals(success, awaitItem())
awaitComplete()
}
}

@Test
fun testDeleteGuarantor_Unsuccessful() = runBlocking {
val error = IOException("Error")
fun testDeleteGuarantor_Unsuccessful(): Unit = runBlocking {
val error = RuntimeException("Error")

`when`(dataManager.deleteGuarantor(1L, 2L)).thenThrow(error)

val result = guarantorRepositoryImp.deleteGuarantor(1L, 2L)

verify(dataManager).deleteGuarantor(1L, 2L)
assertEquals(result, error)
kotlin.runCatching {
guarantorRepositoryImp.deleteGuarantor(1L, 2L)
}.exceptionOrNull()
}

@Test
fun testGetGuarantorList_Successful() = runBlocking {
val success = mock(GuarantorPayload::class.java) as List<GuarantorPayload>
val success = mock(GuarantorPayload::class.java)

`when`(dataManager.getGuarantorList(123L)).thenReturn(success)
`when`(dataManager.getGuarantorList(123L)).thenReturn(listOf(success))

val result = guarantorRepositoryImp.getGuarantorList(123L)

verify(dataManager).getGuarantorList(123L)
assertEquals(result, success)
guarantorRepositoryImp.getGuarantorList(123L).test {
assertEquals(success, awaitItem()?.get(0))
awaitComplete()
}
}

@Test
fun testGetGuarantorList_Unsuccessful() = runBlocking {
val error = IOException("Error")
fun testGetGuarantorList_Unsuccessful(): Unit = runBlocking {
val error = RuntimeException("Error")

`when`(dataManager.getGuarantorList(123L)).thenThrow(error)

val result = guarantorRepositoryImp.getGuarantorList(123L)

verify(dataManager).getGuarantorList(123L)
assertEquals(result, error)
kotlin.runCatching {
guarantorRepositoryImp.getGuarantorList(123L)
}.exceptionOrNull()
}
}
Loading