Skip to content

Commit afb643f

Browse files
[KTLN-530] Serialize/Deserialize Kotlin Sealed Class (#1031)
* added unit test * added unit test * added moshi version to properties in pom
1 parent 220ea79 commit afb643f

File tree

3 files changed

+161
-0
lines changed

3 files changed

+161
-0
lines changed

core-kotlin-modules/core-kotlin-advanced-3/pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@
2020
<version>${kotlinx-html-jvm.version}</version>
2121
</dependency>
2222

23+
<dependency>
24+
<groupId>org.jetbrains.kotlinx</groupId>
25+
<artifactId>kotlinx-serialization-json</artifactId>
26+
<version>${serialization.version}</version>
27+
</dependency>
28+
2329
<dependency>
2430
<groupId>io.github.classgraph</groupId>
2531
<artifactId>classgraph</artifactId>
@@ -64,6 +70,7 @@
6470
</execution>
6571
</executions>
6672
</plugin>
73+
6774
</plugins>
6875
</build>
6976

kotlin-json-2/pom.xml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
<version>1.0.0-SNAPSHOT</version>
1313
</parent>
1414

15+
<properties>
16+
<moshi.version>1.14.0</moshi.version>
17+
</properties>
1518
<dependencies>
1619
<dependency>
1720
<groupId>com.fasterxml.jackson.module</groupId>
@@ -43,5 +46,54 @@
4346
<artifactId>kotlinx-serialization-core-jvm</artifactId>
4447
<version>${serialization.version}</version>
4548
</dependency>
49+
50+
<dependency>
51+
<groupId>com.squareup.moshi</groupId>
52+
<artifactId>moshi</artifactId>
53+
<version>${moshi.version}</version>
54+
</dependency>
55+
56+
<dependency>
57+
<groupId>com.squareup.moshi</groupId>
58+
<artifactId>moshi-kotlin</artifactId>
59+
<version>${moshi.version}</version>
60+
</dependency>
61+
62+
<dependency>
63+
<groupId>com.squareup.moshi</groupId>
64+
<artifactId>moshi-adapters</artifactId>
65+
<version>${moshi.version}</version>
66+
</dependency>
4667
</dependencies>
68+
69+
<build>
70+
<plugins>
71+
<plugin>
72+
<groupId>org.jetbrains.kotlin</groupId>
73+
<artifactId>kotlin-maven-plugin</artifactId>
74+
<version>${kotlin.version}</version>
75+
<executions>
76+
<execution>
77+
<id>compile</id>
78+
<phase>compile</phase>
79+
<goals>
80+
<goal>compile</goal>
81+
</goals>
82+
</execution>
83+
</executions>
84+
<configuration>
85+
<compilerPlugins>
86+
<plugin>kotlinx-serialization</plugin>
87+
</compilerPlugins>
88+
</configuration>
89+
<dependencies>
90+
<dependency>
91+
<groupId>org.jetbrains.kotlin</groupId>
92+
<artifactId>kotlin-maven-serialization</artifactId>
93+
<version>${kotlin.version}</version>
94+
</dependency>
95+
</dependencies>
96+
</plugin>
97+
</plugins>
98+
</build>
4799
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package com.baeldung.serializeAndDeserializeSealedClass
2+
3+
import com.squareup.moshi.Moshi
4+
import com.squareup.moshi.adapters.PolymorphicJsonAdapterFactory
5+
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
6+
import kotlinx.serialization.SerialName
7+
import kotlinx.serialization.Serializable
8+
import kotlinx.serialization.decodeFromString
9+
import kotlinx.serialization.encodeToString
10+
import kotlinx.serialization.json.Json
11+
import kotlinx.serialization.modules.SerializersModule
12+
import kotlinx.serialization.modules.polymorphic
13+
import org.junit.jupiter.api.Assertions.assertEquals
14+
import org.junit.jupiter.api.Test
15+
16+
@Serializable
17+
sealed class Animal {
18+
abstract val name: String
19+
20+
@Serializable
21+
data class Dog(override val name: String, val breed: String) : Animal()
22+
23+
@Serializable
24+
data class Cat(override val name: String, val color: String) : Animal()
25+
}
26+
27+
class SerializeAndDeserializeSealedClassUnitTest {
28+
29+
val moshi: Moshi = Moshi.Builder()
30+
.add(
31+
PolymorphicJsonAdapterFactory.of(Animal::class.java, "type")
32+
.withSubtype(Animal.Dog::class.java, "dog")
33+
.withSubtype(Animal.Cat::class.java, "cat")
34+
)
35+
.add(KotlinJsonAdapterFactory())
36+
.build()
37+
38+
@Test
39+
fun `serialize sealed class using kotlinx serialization library`() {
40+
val dog = Animal.Dog("Buddy", "Labrador")
41+
val serializedDog = Json.encodeToString(dog)
42+
43+
val cat = Animal.Cat("Mike", "Black")
44+
val serializedCat = Json.encodeToString(cat)
45+
46+
assertEquals("{\"name\":\"Buddy\",\"breed\":\"Labrador\"}", serializedDog)
47+
assertEquals("{\"name\":\"Mike\",\"color\":\"Black\"}", serializedCat)
48+
}
49+
50+
@Test
51+
fun `deserialize sealed class using kotlinx serialization library`() {
52+
val json = Json {
53+
serializersModule = SerializersModule {
54+
polymorphic(Animal::class) {
55+
subclass(Animal.Dog::class, Animal.Dog.serializer())
56+
subclass(Animal.Cat::class, Animal.Cat.serializer())
57+
}
58+
}
59+
}
60+
val dog = Animal.Dog("Buddy", "Labrador")
61+
val serializedDog = json.encodeToString(Animal.serializer(), dog)
62+
val deserializedDog = json.decodeFromString<Animal>(serializedDog)
63+
64+
assertEquals(dog, deserializedDog)
65+
66+
val cat = Animal.Cat("Mike", "Black")
67+
val serializedCat = json.encodeToString(Animal.serializer(), cat)
68+
val deserializedCat = json.decodeFromString<Animal>(serializedCat)
69+
70+
assertEquals(cat, deserializedCat)
71+
}
72+
73+
@Test
74+
fun `serialize sealed class using moshi library`() {
75+
76+
val dog = Animal.Dog("Buddy", "Labrador")
77+
val cat = Animal.Cat("Mike", "Black")
78+
79+
val jsonAdapter = moshi.adapter(Animal::class.java)
80+
81+
val serializedDog = jsonAdapter.toJson(dog)
82+
val serializedCat = jsonAdapter.toJson(cat)
83+
84+
assertEquals("{\"type\":\"dog\",\"name\":\"Buddy\",\"breed\":\"Labrador\"}", serializedDog)
85+
assertEquals("{\"type\":\"cat\",\"name\":\"Mike\",\"color\":\"Black\"}", serializedCat)
86+
}
87+
88+
@Test
89+
fun `deserialize sealed class using moshi library`() {
90+
val jsonAdapter = moshi.adapter(Animal::class.java)
91+
92+
val serializedDog = """{"type":"dog","name":"Buddy","breed":"Labrador"}"""
93+
val deserializedDog = jsonAdapter.fromJson(serializedDog) as Animal.Dog
94+
95+
val serializedCat = """{"type":"cat","name":"Mike","color":"Black"}"""
96+
val deserializedCat = jsonAdapter.fromJson(serializedCat) as Animal.Cat
97+
98+
assertEquals(Animal.Dog("Buddy", "Labrador"), deserializedDog)
99+
assertEquals(Animal.Cat("Mike", "Black"), deserializedCat)
100+
}
101+
102+
}

0 commit comments

Comments
 (0)