ViewModel JUnit on JVM & Compose

SeongUg Steve Jung
2 min readJul 1, 2021

Migrating Rule 2 : ViewModel can be tested on JVM

In last posting, I wrote about our rule 1 : try to re-use ViewModel. In a class way, when we build feature code, we should write JUnit test code what can run on JVM. Databinding, it makes help not to write native view code. What we do is to write junit test code on JVM.

By previous Rule 1, we don’t change ViewModel code much. At first, we changed some properties types.

Before building ObservableXXX.observeAsState(), we tried to use LiveData. But there was 2 problems.

  1. LiveData causes to build backing property.

To update LiveData, it isn’t likely ObservableBoolean. we should declare MutableLiveData<>and an interface as LiveData for immutable.

2. MutableLiveData requires UI thread to update value.

Internally MutableLiveData.set() checks caller’s thread if it is main thread. If not, it causes error.

When we run test code with LiveData , we should put a JUnit Test Rule : InstantTaskExecutorRule on JUnit4. and I built our own JUnit5 Extension.

Before getting used it, many developers may get confused like “WHY NOT WORKING MY TEST CODE”

There is an other option : MutableState / State . It has a same problem about backing property. We can avoid it simply like this

But androidx.compose.runtime.State contains lots of functions relate to Compose and I am not fully understand internal mechanism yet.

So we built our own value container for compose and made compatibility for Composable function.

Main purpose is not to expose setter of value directly and doesn’t care about caller Thread for Junit test code on JVM.
Caution : But still ensure main thread to update value. it is required by Jetpack Compose .

Conclusion

Backing property is a bit verbose. But MutableLiveData and MutableState require it. So our team build a Value Container. : ValueHolder

It doesn’t care which thread is called for setter and it exposes setter indirectly.

So.. Let’s move on next rule

Migration Rule 3 : combine Activity Lifecycle with Compose

--

--