This UI component shows a simple screen that uses a ViewModel to manage a counter value. The ViewModel holds the counter state and exposes functions to increase it. The UI observes the ViewModel state and updates the displayed number. Testing the ViewModel means checking that the counter logic works correctly without the UI.
The Activity hosts the ComposeView. The ComposeView displays a Column with a Text widget showing the current counter and a Button to increase it. The ViewModel holds the counter state and is used by the Activity.
Render Trace - 5 Steps
Step 1: Activity
Step 2: ViewModel
Step 3: ComposeView > Column
Step 4: Button
Step 5: Text
State Change - Re-render
Trigger:User taps the 'Increment' button
Before
Counter value = 0
→
After
Counter value = 1
Re-renders:ComposeView subtree including Text displaying counter
UI Quiz - 3 Questions
Test your understanding
What part of the UI updates when the counter changes?
AThe Text widget showing the counter
BThe Button widget
CThe Activity background color
DThe ViewModel instance
Key Insight
Separating UI from logic using a ViewModel lets you test the app's behavior easily without needing the UI. The UI just observes and displays the ViewModel state, so testing the ViewModel ensures your app logic is correct and reliable.
Practice
(1/5)
1.
What is the main purpose of testing a ViewModel in Android development?
easy
A. To validate user input directly on the screen
B. To verify the data handling and business logic without UI involvement
C. To test the navigation between different screens
D. To check the layout and visual appearance of the app
Solution
Step 1: Understand ViewModel role
The ViewModel holds and manages UI-related data but does not handle UI rendering.
Step 2: Identify testing focus
Testing ViewModel focuses on data logic and state management, not UI or navigation.
Final Answer:
To verify the data handling and business logic without UI involvement -> Option B
Quick Check:
ViewModel testing = data logic check [OK]
Hint: ViewModel tests focus on data, not UI or navigation [OK]
Common Mistakes:
Confusing ViewModel testing with UI testing
Thinking ViewModel tests check screen layouts
Assuming navigation is tested in ViewModel tests
2.
Which annotation is commonly used to set up a ViewModel instance before each test method runs?
easy
A. @Ignore
B. @Test
C. @After
D. @Before
Solution
Step 1: Recall JUnit lifecycle annotations
@Before runs before each test method to prepare test environment.
Step 2: Match annotation to ViewModel setup
Use @Before to initialize ViewModel before tests run.
Final Answer:
@Before -> Option D
Quick Check:
Setup before tests = @Before [OK]
Hint: Use @Before to prepare ViewModel before each test [OK]
Common Mistakes:
Using @Test instead of @Before for setup
Confusing @After with setup annotation
Skipping setup annotation entirely
3.
Given the following test code snippet, what will be the value of result after running the test?
class MyViewModelTest {
private lateinit var viewModel: MyViewModel
@Before
fun setup() {
viewModel = MyViewModel()
}
@Test
fun testIncrement() {
viewModel.increment()
val result = viewModel.counter
}
}
Assuming counter starts at 0 and increment() adds 1.
medium
A. 1
B. 0
C. null
D. Throws an exception
Solution
Step 1: Understand initial state
ViewModel's counter starts at 0 before increment.
Step 2: Apply increment method
Calling increment() adds 1, so counter becomes 1.
Final Answer:
1 -> Option A
Quick Check:
Initial 0 + 1 increment = 1 [OK]
Hint: Increment adds 1 to counter starting at 0 [OK]
Common Mistakes:
Assuming counter remains 0 after increment
Thinking result is null without initialization
Expecting an exception without error in code
4.
Identify the error in this ViewModel test code snippet:
class SampleViewModelTest {
private lateinit var viewModel: SampleViewModel
@Test
fun testReset() {
viewModel.reset()
assertEquals(0, viewModel.counter)
}
}
Assuming viewModel is not initialized anywhere else.
medium
A. Missing @Before setup to initialize viewModel before test
B. Incorrect assertEquals parameter order
C. reset() method does not exist in ViewModel
D. Test method missing @Test annotation
Solution
Step 1: Check viewModel initialization
viewModel is declared but never initialized before test runs.
Step 2: Identify missing setup
Without @Before method to initialize viewModel, calling reset() causes error.
Final Answer:
Missing @Before setup to initialize viewModel before test -> Option A
Quick Check:
Initialize viewModel before test = @Before needed [OK]
Hint: Always initialize ViewModel before tests with @Before [OK]
Common Mistakes:
Forgetting to initialize viewModel before use
Mixing assertEquals parameter order
Assuming reset() method is missing without checking
5.
You want to test a ViewModel method that fetches data asynchronously and updates a LiveData property. Which approach is best to test this behavior?
hard
A. Mock the LiveData property and verify it was called
B. Call the method and immediately check LiveData value without waiting
C. Use a coroutine test rule to run suspend functions and observe LiveData changes synchronously
D. Test only the UI observing the LiveData, not the ViewModel method
Solution
Step 1: Understand asynchronous data fetching
ViewModel uses coroutines to fetch data and update LiveData asynchronously.
Step 2: Use coroutine test tools
Coroutine test rules allow running suspend functions in tests synchronously for reliable assertions.
Step 3: Observe LiveData changes properly
Observing LiveData synchronously ensures test waits for updates before asserting values.
Final Answer:
Use a coroutine test rule to run suspend functions and observe LiveData changes synchronously -> Option C
Quick Check:
Async ViewModel test = coroutine test rule + LiveData observe [OK]
Hint: Use coroutine test rule to handle async LiveData updates [OK]
Common Mistakes:
Checking LiveData immediately without waiting
Mocking LiveData instead of testing real updates
Testing UI instead of ViewModel logic
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.