Photo by Jakob Owens

Sealed Classes Unit Tests💥

Fernando Prieto
2 min readJul 1, 2020

Some months ago, I was working in an Android project where I decided to create a view template that based on the sealed class received on the view, I was able to show different layout structures: one of those possible view structures would have a title, subtitle and image. Another one, those three elements plus an extra text field and so forth.

At some point, I felt the need of testing the type of sealed class that the View Model was able to notify the observer (View) through LiveData. And I found an interesting post by Danny Preussler, where he explained a great approach using some factories, annotations and generics (Parameterized tests with Kotlin’s Sealed Classes).

In his project, he was able to test many different sealed classes : simple, nested and custom. But I decided to focus on the custom one, which is the most common type that I usually work with: different data classes within the sealed class, each one, with different parameters.

I used some common parameters in all of the sealed sub-classes. To achieve that, I defined an interface that had got all of those parameters:

And the sealed class I defined, as example, implementing that interface is:

As you can see, it contains a class ErrorCode , annotated with @InstagramErrorCode, which I will explain later:

Test goals 🎯

The first thing I wanted to test was, the expected sealed sub-class, using Parameterized Test . So I could pass as arguments the different cases with the expected KClass.

And the second thing, I wanted to achieve in my test was the different constructors availability check. That confirms the number of data classes defined within the sealed class .

Parameterized Test by Type 🔬

Test by Class 📦

WHY another custom Factory ⁉️

In order to use the class developed by Danny Preussler SealedClassesArgumentsProvider , we need to identify and return a type value from the KClassifier represented by every parameter.

As I decided to add a List and an Enum Class , I must specify the returned value. And in the case of the Enum Class , I thought that an interesting way to do it, was finding the annotation specified for that class, then returning a default Enum Type asErrorCode.TimeOut

WHY another annotation ⁉️

When I was specifying the return type from the KClassifier I found there was a better solution than the first approach (hardcoded value) I made.
Let’s compare this initial solution (NOT GOOD):

else -> if ((type.classifier as KClass<out Any>).qualifiedName == “sctestingplayground.ErrorCode”) ErrorCode.TimeOut else null

And let’s check now, the improvement using the findAnnotation inline function:

else -> if ((type.classifier as KClass<out Any>).findAnnotation<InstagramErrorCode>() != null) ErrorCode.TimeOut else null

Code

You can find the entire example in my Github Kotlin repository:

SealedClassesTestingPlayground

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Fernando Prieto
Fernando Prieto

Written by Fernando Prieto

Senior Android Developer | Calisthenics Athlete

No responses yet

Write a response