Congratulations, for reaching so far in this course. At the moment, I am sure - you know a lot about lifecycle-aware components.
So let’s wrap this course by exploring how to test a lifecycle-aware component. Because development without writing test case makes me feel incomplete.
While writing test, we need to follow the same three steps which we followed earlier. But this time, of course with a slight difference. So let’s write some test cases.
Ok, so if you open your module level Gradle file - you’ll find all the testing dependencies are already in place. So we don’t have to make any extra effort here.
So my objective is to test the lifecycle-aware component which is NetworkMonitor in our case. Right? So this is our lifecycle-aware component.
So I want to test whether this method onCreate respond to ON_CREATE event or not. So that in return it executes this init() method.
Similarly, we can emit ON_START event and test whether this onStart method is triggered or not.
In the same way, we will test this onStop execution.
So now that we know what to test. Let’s go to our unit testing package. And within that you’ll find a file NetworkMonitorTest. Let’s open it.
It already contain some setup. That’s great.
Now, for this lifecycle-aware component NetworkMonitor the lifecycle owner class was previously MainActivity.
But now since we need to test this NetworkMonitor so within this NetworkMonitorTest class we need to create a mock of LifecycleOwner class. So let’s utilise the testing library and create a mock for that.
Let’s add - this statement.
private val lifecycleOwner = mockk<LifecycleOwner>(relaxed = true)
This inline function mockk will build a mock for this class. Fine?
Similarly, we can create a mock for NetworkMonitor.
private val networkMonitor = mockk<NetworkMonitor>(relaxed = true)
Next, we need to have LifecycleRegistry. So let’s create that as well.
private lateinit var lifecycleRegistry: LifecycleRegistry
And, within this setup() function, let’s initialize the LifecycleRegistry and as a parameter pass our lifecycleOwner mock. Like this!
lifecycleRegistry = LifecycleRegistry(lifecycleOwner)
And then we need to make our networkMonitor subscribe to our LifecycleOwner which we just created. So for that, we can use lifecycleRegistry.addObserver() method and pass our observer such as networkMonitor.
lifecycleRegistry.addObserver(networkMonitor)
@Before
fun setup() {
lifecycleRegistry = LifecycleRegistry(lifecycleOwner)
lifecycleRegistry.addObserver(networkMonitor)
}
Perfect! So now, all the three steps are completed. So it’s time to write our first test case. Let’s add a function with @Test annotation.
@Test
fun `When dispatching ON_CREATE lifecycle event, call onCreate()`() {
}
So the purpose of this function is to dispatch ON_CREATE lifecycle event and check whether this onCreate function is getting executed in the NetworkMonitor class or not.
So you can use this back-tick, over here and here, to give meaningful name to your test function. Fine?
So we will lifecycleRegistry.handleLifecycleEvent() method to dispatch ON_CREATE event.
We have already used this function in our earlier episode. Remember while creating the custom LifecycleOwner class we used it?
Next, to verify the execution of onCreate method on dispatch of this event we can use verify { } lambda and then pass networkMonitor.onCreate(). This wil verify if this function is getting executed or not.
verify {
networkMonitor.onCreate(lifecycleOwner)
}
So, let’s run our first test.
@Test
fun `When dispatching ON_CREATE lifecycle event, call onCreate()`() {
// 1. Notify observers and set the lifecycle state.
lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
// 2. Verify the execution of the correct method.
verify {
networkMonitor.onCreate(lifecycleOwner)
}
}
So yes, our test passed. Similarly, we can write two more test cases. For onStart and onStop method execution.
So I will just copy this test case, paste it over here. And change this function name such as ON_START and here let’s change it to onStart function.
And instead of ON_CREATE event emission, let’s emit ON_START.
And instead of this onCreate let’s use onStartfunction. Great!
@Test
fun `When dispatching ON_START lifecycle event, call onStart()`() {
// 1. Notify observers and set the lifecycle state.
lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START)
verify {
networkMonitor.onStart(lifecycleOwner)
}
}
Let’s test this function as well. Again, our test passed.
Similarly, we can test our onStop function.
Again I will copy this code and paste it here and this time instead of dispatching ON_START we will dispatch ON_STOP event and test the execution of onStop method. Let’s try it out.
But this time our test failed. Let’s check out what’s the error. It says “Verification failed: call 1 of 1”. The onStop method was not called.
Now, this is because, we are expecting to directly execute onStop method by bypassing the lifecycle flow. So in order to execute onStop we should atleast execute onStart method. It’s like how can you stop something which has not yet started. Right?
So the solution for this test case is that we need to first emit or trigger ON_START event. So first ON_START event emission will execute the onStart method and then when we emit this ON_STOP event, it is going to execute successfully the onStop method which we are about to verify.
Great! Our test passed successfully this time.
@Test
fun `When dispatching ON_STOP lifecycle event, call onStop()`() {
// 1. Notify observers and set the lifecycle state.
lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START)
lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP)
// 2. Verify the execution of the correct method.
verify {
networkMonitor.onStop(lifecycleOwner)
}
}
Now, for the last time, for my satisfaction as a developer, let’s run the entire three tests at once. Amazing! I feel like at the top of the world when all the test case pass in my projects. So yes, this is how we write test cases for lifecycle-aware components.
Again congratulations for reaching the end of this course. It’s time to summarise what we have learnt so far.
Well, we learnt about what is a lifecycle-aware component and how to create it.
We explored what are lifecycles and
what are lifecycle observers in Android?
We dived further by exploring what are lifecycle events and states for both activities and fragments.
We learnt how to create our own custom lifecycle owner.
Then we explored in-built lifecycle-aware component such as LiveData.
Lastly, we learnt to how to test lifecycle-aware components. So I hope you enjoyed learning from this course as much as I did while creating it.
Hope to see you in another course, until then take care and have a nice day. Bye!