You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fix ViewModel constructor errors in ViewModelUiTests
Rewrote ViewModelUiTests to use StateFlow-based testing instead of
attempting to instantiate ViewModels directly. The ViewModels in this
project use Koin dependency injection and don't accept constructor
parameters, which was causing "Too many arguments for constructor" errors.
Changes:
ViewModelUiTests.kt:
- Removed attempts to instantiate ViewModels with repository parameters
- Changed to StateFlow-based testing pattern using MutableStateFlow
- Added new tests demonstrating state transitions (Loading → Success → Error)
- Added test for ISS position state updates
- Added tests for all PersonListUiState variants (Loading, Success, Error)
- Added test demonstrating state transition from Loading to Success
- Updated documentation in comments to explain the testing approach
- All test composables now accept StateFlow parameters instead of ViewModels
New test coverage:
- testISSPositionDisplay_withStateFlow
- testISSPositionUpdate_whenStateChanges
- testPersonListSuccess_displaysData
- testPersonListLoading_displaysLoadingIndicator
- testPersonListError_displaysError
- testPersonListDisplaysCorrectCount
- testPersonListStateTransition_fromLoadingToSuccess
README.md:
- Updated ViewModelUiTests description to reflect state-based testing
- Added new section "Testing State-Based UI Components"
- Replaced ViewModel instantiation examples with StateFlow examples
- Added explanation of why StateFlow is used instead of actual ViewModels
- Updated code examples to show state transition testing
- Added note about Koin dependency injection in ViewModels
Benefits of this approach:
- Tests the UI layer independently of ViewModel implementation
- No need to set up complex Koin test modules
- More focused on UI behavior rather than ViewModel internals
- Easier to test different state scenarios
- Demonstrates practical testing patterns for StateFlow-based UIs
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
Copy file name to clipboardExpand all lines: common/src/commonTest/kotlin/README.md
+50-16Lines changed: 50 additions & 16 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -22,11 +22,12 @@ Tests for ISS position display components:
22
22
- Demonstrating data-driven testing patterns
23
23
24
24
### 3. `ViewModelUiTests.kt`
25
-
Advanced tests showing ViewModel integration:
26
-
- Testing UI components connected to ViewModels
25
+
Advanced tests showing state-based UI testing:
26
+
- Testing UI components with StateFlow (the pattern used by ViewModels)
27
27
- Managing coroutine test dispatchers
28
-
- Testing state flow updates
29
-
- Verifying UI reflects ViewModel state changes
28
+
- Testing state transitions (Loading → Success → Error)
29
+
- Verifying UI reacts to state changes
30
+
- Note: Uses StateFlow directly instead of actual ViewModels (which use Koin DI)
30
31
31
32
### 4. `TestTagExampleTests.kt`
32
33
Best practices for using test tags:
@@ -230,9 +231,9 @@ fun testButtonClick() = runComposeUiTest {
230
231
}
231
232
```
232
233
233
-
## Testing ViewModels
234
+
## Testing State-Based UI Components
234
235
235
-
When testing components with ViewModels:
236
+
The ViewModels in this project use Koin dependency injection and don't accept constructor parameters. Therefore, UI tests focus on testing components with StateFlow directly:
236
237
237
238
1.**Setup test dispatcher**:
238
239
```kotlin
@@ -249,17 +250,32 @@ fun tearDown() {
249
250
}
250
251
```
251
252
252
-
2.**Advance time for coroutines**:
253
+
2.**Create mock state flows**:
253
254
```kotlin
254
-
testDispatcher.scheduler.advanceUntilIdle()
255
+
val uiStateFlow =MutableStateFlow(PersonListUiState.Success(fakeData))
256
+
```
257
+
258
+
3.**Test state transitions**:
259
+
```kotlin
260
+
// Start with loading
261
+
val stateFlow =MutableStateFlow(UiState.Loading)
262
+
setContent { MyComposable(stateFlow) }
263
+
onNodeWithText("Loading...").assertIsDisplayed()
264
+
265
+
// Transition to success
266
+
stateFlow.value =UiState.Success(data)
255
267
waitForIdle()
268
+
onNodeWithText("Data").assertIsDisplayed()
256
269
```
257
270
258
-
3.**Use fake repositories**:
271
+
4.**Advance time for coroutines**:
259
272
```kotlin
260
-
val viewModel =MyViewModel(fakeRepository)
273
+
testDispatcher.scheduler.advanceUntilIdle()
274
+
waitForIdle()
261
275
```
262
276
277
+
This approach tests the UI layer independently of ViewModel implementation details.
278
+
263
279
## Platform-Specific Considerations
264
280
265
281
### Android
@@ -311,10 +327,10 @@ class CoordinateDisplayTests {
@@ -323,21 +339,39 @@ class ViewModelIntegrationTests {
323
339
}
324
340
325
341
@Test
326
-
funtestWithViewModel() = runComposeUiTest {
327
-
val viewModel =ISSPositionViewModel(fakeRepository)
342
+
funtestWithStateFlow() = runComposeUiTest {
343
+
// Create mock state flow
344
+
val positionFlow =MutableStateFlow(IssPosition(53.27, -9.05))
328
345
329
346
setContent {
330
-
ISSPositionContent(viewModel)
347
+
// Composable that accepts StateFlow
348
+
ISSPositionContent(positionFlow)
331
349
}
332
350
333
351
testDispatcher.scheduler.advanceUntilIdle()
334
352
waitForIdle()
335
353
336
-
onNodeWithText("53.2743394").assertIsDisplayed()
354
+
onNodeWithText("53.27").assertIsDisplayed()
355
+
}
356
+
357
+
@Test
358
+
funtestStateTransition() = runComposeUiTest {
359
+
val stateFlow =MutableStateFlow(UiState.Loading)
360
+
setContent { MyComposable(stateFlow) }
361
+
362
+
onNodeWithText("Loading...").assertExists()
363
+
364
+
stateFlow.value =UiState.Success(data)
365
+
waitForIdle()
366
+
367
+
onNodeWithText("Success").assertExists()
337
368
}
338
369
}
339
370
```
340
371
372
+
**Why StateFlow instead of actual ViewModels?**
373
+
The ViewModels in this project use Koin for dependency injection and don't accept constructor parameters. Testing with StateFlow allows us to test the UI layer independently without setting up complex Koin test modules.
0 commit comments