Skip to content

Commit 3f26255

Browse files
committed
Adding unit tests for ViewModel
1 parent 88d1f75 commit 3f26255

File tree

2 files changed

+94
-8
lines changed

2 files changed

+94
-8
lines changed

vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ class RoomPollsViewModel @AssistedInject constructor(
8282
.launchIn(viewModelScope)
8383
}
8484

85-
// TODO add unit tests
8685
override fun handle(action: RoomPollsAction) {
8786
when (action) {
8887
RoomPollsAction.LoadMorePolls -> handleLoadMore()

vector/src/test/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModelTest.kt

Lines changed: 94 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,25 @@
1717
package im.vector.app.features.roomprofile.polls
1818

1919
import com.airbnb.mvrx.test.MavericksTestRule
20+
import im.vector.app.features.roomprofile.polls.list.data.LoadedPollsStatus
2021
import im.vector.app.features.roomprofile.polls.list.domain.GetLoadedPollsStatusUseCase
21-
import im.vector.app.features.roomprofile.polls.list.ui.PollSummary
2222
import im.vector.app.features.roomprofile.polls.list.domain.GetPollsUseCase
2323
import im.vector.app.features.roomprofile.polls.list.domain.LoadMorePollsUseCase
2424
import im.vector.app.features.roomprofile.polls.list.domain.SyncPollsUseCase
25+
import im.vector.app.features.roomprofile.polls.list.ui.PollSummary
2526
import im.vector.app.test.test
2627
import im.vector.app.test.testDispatcher
28+
import io.mockk.coEvery
29+
import io.mockk.coJustRun
30+
import io.mockk.coVerify
2731
import io.mockk.every
2832
import io.mockk.mockk
2933
import io.mockk.verify
3034
import kotlinx.coroutines.flow.flowOf
3135
import org.junit.Rule
3236
import org.junit.Test
3337

34-
private const val ROOM_ID = "room-id"
38+
private const val A_ROOM_ID = "room-id"
3539

3640
class RoomPollsViewModelTest {
3741

@@ -42,7 +46,7 @@ class RoomPollsViewModelTest {
4246
private val fakeGetLoadedPollsStatusUseCase = mockk<GetLoadedPollsStatusUseCase>()
4347
private val fakeLoadMorePollsUseCase = mockk<LoadMorePollsUseCase>()
4448
private val fakeSyncPollsUseCase = mockk<SyncPollsUseCase>()
45-
private val initialState = RoomPollsViewState(ROOM_ID)
49+
private val initialState = RoomPollsViewState(A_ROOM_ID)
4650

4751
private fun createViewModel(): RoomPollsViewModel {
4852
return RoomPollsViewModel(
@@ -55,11 +59,17 @@ class RoomPollsViewModelTest {
5559
}
5660

5761
@Test
58-
fun `given viewModel when created then polls list is observed and viewState is updated`() {
62+
fun `given viewModel when created then polls list is observed, sync is launched and viewState is updated`() {
5963
// Given
64+
val loadedPollsStatus = givenGetLoadedPollsStatusSuccess()
65+
givenSyncPollsWithSuccess()
6066
val polls = listOf(givenAPollSummary())
61-
every { fakeGetPollsUseCase.execute(ROOM_ID) } returns flowOf(polls)
62-
val expectedViewState = initialState.copy(polls = polls)
67+
every { fakeGetPollsUseCase.execute(A_ROOM_ID) } returns flowOf(polls)
68+
val expectedViewState = initialState.copy(
69+
polls = polls,
70+
canLoadMore = loadedPollsStatus.canLoadMore,
71+
nbLoadedDays = loadedPollsStatus.nbLoadedDays,
72+
)
6373

6474
// When
6575
val viewModel = createViewModel()
@@ -70,11 +80,88 @@ class RoomPollsViewModelTest {
7080
.assertLatestState(expectedViewState)
7181
.finish()
7282
verify {
73-
fakeGetPollsUseCase.execute(ROOM_ID)
83+
fakeGetPollsUseCase.execute(A_ROOM_ID)
7484
}
85+
coVerify { fakeSyncPollsUseCase.execute(A_ROOM_ID) }
86+
}
87+
88+
@Test
89+
fun `given viewModel and error during sync process when created then error is raised in view event`() {
90+
// Given
91+
givenGetLoadedPollsStatusSuccess()
92+
givenSyncPollsWithError(Exception())
93+
val polls = listOf(givenAPollSummary())
94+
every { fakeGetPollsUseCase.execute(A_ROOM_ID) } returns flowOf(polls)
95+
96+
// When
97+
val viewModel = createViewModel()
98+
val viewModelTest = viewModel.test()
99+
100+
// Then
101+
viewModelTest
102+
.assertEvents(RoomPollsViewEvent.LoadingError)
103+
.finish()
104+
coVerify { fakeSyncPollsUseCase.execute(A_ROOM_ID) }
105+
}
106+
107+
@Test
108+
fun `given viewModel when handle load more action then viewState is updated`() {
109+
// Given
110+
val loadedPollsStatus = givenGetLoadedPollsStatusSuccess()
111+
givenSyncPollsWithSuccess()
112+
val polls = listOf(givenAPollSummary())
113+
every { fakeGetPollsUseCase.execute(A_ROOM_ID) } returns flowOf(polls)
114+
val newLoadedPollsStatus = givenLoadMoreWithSuccess()
115+
val viewModel = createViewModel()
116+
val stateAfterInit = initialState.copy(
117+
polls = polls,
118+
canLoadMore = loadedPollsStatus.canLoadMore,
119+
nbLoadedDays = loadedPollsStatus.nbLoadedDays,
120+
)
121+
122+
// When
123+
val viewModelTest = viewModel.test()
124+
viewModel.handle(RoomPollsAction.LoadMorePolls)
125+
126+
// Then
127+
viewModelTest
128+
.assertStatesChanges(
129+
stateAfterInit,
130+
{ copy(isLoadingMore = true) },
131+
{ copy(canLoadMore = newLoadedPollsStatus.canLoadMore, nbLoadedDays = newLoadedPollsStatus.nbLoadedDays) },
132+
{ copy(isLoadingMore = false) },
133+
)
134+
.finish()
135+
coVerify { fakeLoadMorePollsUseCase.execute(A_ROOM_ID) }
75136
}
76137

77138
private fun givenAPollSummary(): PollSummary {
78139
return mockk()
79140
}
141+
142+
private fun givenSyncPollsWithSuccess() {
143+
coJustRun { fakeSyncPollsUseCase.execute(A_ROOM_ID) }
144+
}
145+
146+
private fun givenSyncPollsWithError(error: Exception) {
147+
coEvery { fakeSyncPollsUseCase.execute(A_ROOM_ID) } throws error
148+
}
149+
150+
private fun givenLoadMoreWithSuccess(): LoadedPollsStatus {
151+
val loadedPollsStatus = givenALoadedPollsStatus(canLoadMore = false, nbLoadedDays = 20)
152+
coEvery { fakeLoadMorePollsUseCase.execute(A_ROOM_ID) } returns loadedPollsStatus
153+
return loadedPollsStatus
154+
}
155+
156+
private fun givenGetLoadedPollsStatusSuccess(): LoadedPollsStatus {
157+
val loadedPollsStatus = givenALoadedPollsStatus()
158+
every { fakeGetLoadedPollsStatusUseCase.execute(A_ROOM_ID) } returns loadedPollsStatus
159+
return loadedPollsStatus
160+
}
161+
162+
private fun givenALoadedPollsStatus(canLoadMore: Boolean = true, nbLoadedDays: Int = 10) =
163+
LoadedPollsStatus(
164+
canLoadMore = canLoadMore,
165+
nbLoadedDays = nbLoadedDays,
166+
)
80167
}

0 commit comments

Comments
 (0)