Search code examples
javaspringunit-testingkotlindeserialization

How to unit-test StdDeserializer in spring boot?


The JSON object that is deserialized is of this format.

{
   "myTypes":["type-1","type-2"...]
}

The deserializer class is as follows.

class MyDeserializer: StdDeserializer<MyType>( MyType::class.java) {
    override fun deserialize(jsonPareser: JsonParser?, dctx: DeserializationContext?): MyType? {
        val node: JsonNode = jsonPareser?.codec?.readTree(jsonPareser) ?: return null
        return try {
            MyType.valueOf(node.textValue().uppercase().replace('-','_'))
        }catch (e : IllegalArgumentException){
            null
        }
    }

I have written most of the tests but can't figure out what to do in the mentioned part.

class MyTypeDeserializerTest {
    @BeforeEach
    fun init() {
        MockKAnnotations.init(this)
    }

    @ParameterizedTest(name = "given string \"{0}\" is valid:  \"{1}\"")
    @MethodSource("tests")
    fun `check different parameters`(string: String, myType: MyType) {
        val myTypeDeserializer = MyTypeDeserializer()
        val deserialisedType= myTypeDeserializer.deserialize(<what do I put here?>)

        Assertions.assertEquals(myType, deserialisedType)
    }

    private companion object {
        @JvmStatic
        fun tests() = Stream.of(
            Arguments.of(String.format(<josn>), expectedType),
        )
    }

}

Help would be much appreciated


Solution

  • You can do a sort of integration test to test your code.

    
        @ParameterizedTest(name = "given string \"{0}\" is valid:  \"{1}\"")
        @MethodSource("tests")
        fun `check different parameters`(string: String, myType: MyType) {
        
            // create a jackson object mapper instance and register your own deserializer
            val mapper = ObjectMapper().registerKotlinModule().registerModule(SimpleModule().apply {
                addDeserializer(MyType::class.java, MyDeserializer())
            })    
                    
            // read the serialized string into an object using your deserializer
            Assertions.assertEquals(myType, mapper.readValue<MyType>(string))
        
        }
    
    

    The example assumed that the jackson-module-kotlin(Maven Repository) is available within the classpath. Alternativly you should use mapper.readValue(serialized, MyType::class.java) to deserialize your json and should skip adding registerKotlinModule() to the object mapper builder.