Android MVVM Basics

If you look in the super class of MainViewModel you will only see this:public abstract class ViewModel { /** * This method will be called when this ViewModel is no longer used and will be destroyed.

* <p> * It is useful when ViewModel observes some data and you need to clear this subscription to * prevent a leak of this ViewModel.

*/ @SuppressWarnings("WeakerAccess") protected void onCleared() { }}So let’s add some functionality to the MainViewModel class.

For this example we are going to implement a Login form.

Assuming we have both a username and password EditText on our activity we can inform the viewModel of changes with the help of Android-ktx, a useful set of Kotlin Extension functions that make Android code easier to write.

Now that we have the input wired to inform the viewModel of changes to the EditTexts, we can implement some logic in the MainViewModel class.

There is quite a bit of code added here, but it is all fairly basic.

First we are initializing username and password String variables, with custom setters that call a form validation function.

We are also declaring a private MutableLiveData of type Boolean, and a public LiveData of type Boolean.

This is an important distinction.

It may look like we are doubling up our code, but really it is protecting the MutableLiveData from being updated outside of the MainViewModel class.

When the user inputs text, the validateForm function is called.

If the form is considered valid by the business logic, it will post a new Boolean value to the internal MutableLiveData.

Let’s go back to the view and do something when that happens!With the final line in onCreate we are declaring that the MainActivity is going to observe the value produced by the isFormValid LiveData from the MainViewModel class.

If the LiveData produces a true value, we will enable the login button.

Working Perfectly!TestingThis is a good little bit of functionality, but not something we couldn’t have done without ViewModels and LiveData.

The real power of these two come from the ability to unit test your business logic of the application.

If you notice from the code above, there is no actual logic in the Activity.

This is a good thing.

Logic should be tested, and activities are considered “heavy” to test.

They either need a framework like Robolectric to mock or Espresso to run test versions.

By moving the logic into the ViewModel, we can now write unit tests that are speedy and accurate.

There’s quite a bit new in this snippet, but it shouldn’t be too overwhelming.

First we need to declare a mock Observer for the LiveData from the ViewModel.

We are going to do this using MockK, a powerful mocking library for Kotlin that works very well for Android.

We then declare a setup method that initializes the mock and the system under test before each unit test is ran.

The system under test in this case is the MainViewModel instance.

Then our actual unit test is declared.

First, set up the mockObserver to observe the validation LiveData.

Second, feed the viewModel data like the user would.

In this test we are setting the username, setting the password, then setting the username again.

MockK provides functionality to verify events happen in order, which is very useful for testing LiveData.

The user flow we are testing looks like this:Wrapping UpWe’ve implemented a simple login form in Android with ViewModel, LiveData, and Kotlin.

Our important business logic is backed by a fast running unit tests using a powerful modern mocking framework.

This is just scratching the surface of what ViewModel can do.

I look forward to hearing about your ViewModel experiences, what causes trouble, or what other tutorials you would like to see.

Thanks for reading!.

. More details

Leave a Reply