How To Make Unit Tests for ViewModel Easier To Write and Maintain

Assist your self and others with clear code

Picture by Tony Pepe on Unsplash

I’m an enormous fan of TDD. However my TDD used to complete as quickly as I began to write down code for ViewModel. I used to undergo from messes my unit exams turned. The extra logic I added to ViewModel, the extra messes I produced in unit exams.

Finally, I used to finish up deleting exams for ViewModel as a result of it was too troublesome to keep up and write a brand new one. However with out exams I used to undergo from bugs that I (or one other developer) had launched.

So why is it troublesome to write down unit exams for ViewModel?

  1. ViewModel of a posh display could include ten or extra dependencies.
  2. Each class that ViewModel relies on have a number of public strategies that ViewModel makes use of.
  3. Some public strategies could return completely different outcomes that change ViewModel’s behaviour.
  4. Typically, it’s wanted to confirm a sequence of calls of a category or lessons. For instance, it may be states of views, one view is proven and one other is hidden. It will also be the case when it’s wanted to confirm that one technique of a category that has been referred to as, however one other hasn’t.
  5. Furthermore, it might be nice to reuse code in unit exams.

So let me slim down the listing of all the difficulties to a few easy questions:

  1. How you can deal with the complexity of state verifying of ViewModel?
  2. How you can deal with the complexity of the instantiation of ViewModel?
  3. How you can deal with the complexity of interactions with ViewModels?

However earlier than I begin answering these questions, I’d like a say a few issues:

  1. This text is about easy methods to set up exams for ViewModel that will help you simply keep and write new ones.
  2. I’m going to maintain examples so simple as attainable. Options may seem like overengineering, however they shine in an actual mission. On the finish of the article, I’ll present snippets of exams for the mission I’m engaged on.

Let’s start.

Let’s contemplate the straightforward load/content material/error case:

  • The loader state is proven when information is being fetched.
  • The content material state is proven if information has been loaded efficiently.
  • The error state is proven if information has been loaded with an error.
  • Knowledge is loaded and proven when a consumer clicks on the retry button.

Let’s additionally write unit exams like this one proven under:

Doable answer: I discover it useful to make use of Verifier. Verifier is the utility class that incorporates verifying logic.

So, after refactoring SomeViewModelTest, it seems like that:

Listed below are some advantages of Verifier:

  1. It will increase the readability of unit exams.
  2. It reduces code duplication.
  3. Android Studio may give hints about what will be verified. So it’s tougher to overlook one thing if you write a brand new check.
Particularly helpful for brand new exams or refactoring the previous ones

Doable answer: I discover it useful to make use of ViewModelBuilder. ViewModelBuilder is a utility class that’s answerable for configuring ViewModel to fulfil our wants.

Mocking logic has been moved to the ViewModelBuilder. It’s essential to provide descriptive names for every technique with the intention to spend much less psychological efforts studying the physique of a check operate.

Let’s refactor SomeViewModelTest:

Listed below are the advantages of ViewModelBuilder:

  1. Mocking logic will be reused in several exams.
  2. Improve the readability of unit exams. Instantiation of view mannequin doesn’t produce messes.
  3. Android Studio may give hints about what will be mocked.
Particularly helpful for brand new exams or refactoring the previous ones

Doable answer: I discover it useful to make use of the Circumstances class. The Circumstances class is a utility class that encapsulates interplay logic with ViewModel. So it’s answerable for:

  1. Mocking dependencies after ViewModel’s instantiation.
  2. Encapsulation of interplay logic with ViewModel (e.g. calling public strategies for clicks or public strategies that Fragment or Exercise calls, and so forth).

Is critical to have the Case class?

I imagine it’s. Interactions with ViewModel may very well be fairly complicated. It’s typically wanted to name the identical public strategies of ViewModel in a particular order again and again for brand new exams. There may be sizzling observables that emit occasions at a random or specific time that adjustments ViewModel’s behaviour.

Instance

Let’s contemplate a easy instance:

  1. ViewModel’s information is loaded with an error.
  2. A consumer clicks on the retry button
  3. ViewModel’s information is loaded efficiently and proven.

Let’s write the Circumstances class:

And the check seems like this:

Advantages of getting the Circumstances class:

  1. It permits reusing interplay logic between exams.
  2. Specific naming of strategies of Circumstances class provides an specific thought of what’s occurring in a check. So it will increase readability.
  3. Android Studio provides hints about what case can be utilized:
Particularly helpful for brand new exams or refactoring the previous ones

Examine these two unit exams under. The primary one is written carelessly. The second is written in response to the approaches.

The unit check that’s written carelessly
The unit check with patterns

These are solely 2 of the 42 unit exams which have been written.

If unit exams are written utilizing the primary strategy, it’s difficult to write down a brand new one or change the previous one due to poor readability. There are additionally a variety of code duplications.

The second strategy eliminates all of those disadvantages.

More Posts