Kotlin Класс данных Джексона сериализации / десериализации одного объекта не удался - PullRequest
1 голос
/ 28 апреля 2020

В настоящее время я работаю над проектом Kotlin, в котором мы используем Джексона для сериализации / десериализации наших data class ов. Я начинаю писать некоторые модульные тесты и рассказываю, что при создании экземпляра data class после его сериализации и последующей десериализации я получал разные объекты.

Вот что я имею в виду:

Мой класс данных

data class TestEvent(
    @JsonProperty("stringProperty")
    val stringProperty: String,

    @JsonProperty("intProperty") 
    val intProperty: Int? = null,

    @JsonProperty("int32Property") 
    val int32Property: Int? = null,

    @JsonProperty("int64Property") 
    val int64Property: Long? = null,

    @JsonProperty("floatProperty") 
    val floatProperty: Float? = null,

    @JsonProperty("doubleProperty") 
    val doubleProperty: Double? = null,

    @JsonProperty("byteProperty") 
    val byteProperty: ByteArray? = null,

    @JsonProperty("booleanProperty") 
    val booleanProperty: Boolean? = null,

    @JsonProperty("dateProperty") 
    val dateProperty: java.time.LocalDate? = null,

    @JsonProperty("dateTimeProperty") 
    val dateTimeProperty: java.time.OffsetDateTime? = null,

    @JsonProperty("uuidProperty") 
    val uuidProperty: java.util.UUID? = null
)

Тест

class SerializationTest {

    private lateinit var mapper: ObjectMapper

    @Before
    fun setup() {
        mapper = ObjectMapper()
                .registerModule(KotlinModule())
                .registerModule(JavaTimeModule())
                .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
                .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
                .setSerializationInclusion(JsonInclude.Include.NON_NULL)
    }

    @Test
    fun testJacкsonDeserialize() {
        val testEvent = createTestEvent()
        val serializedEvent = mapper.writeValueAsString(testEvent)
        val deserializedEvent = mapper.readValue(serializedEvent, TestEvent::class.java)
        Assert.assertEquals(testEvent, deserializedEvent)
    }

    fun createTestEvent() = TestEvent(
            stringProperty = "Test event",
            intProperty = 12,
            int32Property = 34,
            int64Property = 54L,
            floatProperty = 12.0f,
            doubleProperty = 566.0,
            byteProperty = byteArrayOf(3, 5, 7, 9),
            booleanProperty = false,
            dateProperty = LocalDate.of(2020, 1, 20),
            dateTimeProperty = OffsetDateTime.of(LocalDate.of(2020, 1, 20), LocalTime.of(10, 0, 10), ZoneOffset.UTC),
            uuidProperty = UUID.fromString("2dd41a88-bf52-42ba-8ab9-d202139582ee")
    )
}

После запуска теста получите следующее исключение:

java.lang.AssertionError: expected: 
TestEvent<TestEvent(stringProperty=Test event, intProperty=12, int32Property=34, int64Property=54, floatProperty=12.0, doubleProperty=566.0, byteProperty=[3, 5, 7, 9], booleanProperty=false, dateProperty=2020-01-20, dateTimeProperty=2020-01-20T10:00:10Z, uuidProperty=2dd41a88-bf52-42ba-8ab9-d202139582ee)> but was: 
TestEvent<TestEvent(stringProperty=Test event, intProperty=12, int32Property=34, int64Property=54, floatProperty=12.0, doubleProperty=566.0, byteProperty=[3, 5, 7, 9], booleanProperty=false, dateProperty=2020-01-20, dateTimeProperty=2020-01-20T10:00:10Z, uuidProperty=2dd41a88-bf52-42ba-8ab9-d202139582ee)>
Expected :TestEvent<TestEvent(stringProperty=Test event, intProperty=12, int32Property=34, int64Property=54, floatProperty=12.0, doubleProperty=566.0, byteProperty=[3, 5, 7, 9], booleanProperty=false, dateProperty=2020-01-20, dateTimeProperty=2020-01-20T10:00:10Z, uuidProperty=2dd41a88-bf52-42ba-8ab9-d202139582ee)> 
Actual   :TestEvent<TestEvent(stringProperty=Test event, intProperty=12, int32Property=34, int64Property=54, floatProperty=12.0, doubleProperty=566.0, byteProperty=[3, 5, 7, 9], booleanProperty=false, dateProperty=2020-01-20, dateTimeProperty=2020-01-20T10:00:10Z, uuidProperty=2dd41a88-bf52-42ba-8ab9-d202139582ee)>

То, как вы видите, что оба объекта одинаковы, но тест не пройден, и единственное, что я вижу в качестве различия, - это сравнительное представление среды IDE, в котором после тега generi c объекта добавлено некоторое пустое пространство, прикрепите снимок экрана:

enter image description here

Я что-то упустил? Не могли бы вы дать совет здесь?

1 Ответ

0 голосов
/ 29 апреля 2020

После дня, размышляя и исследуя, что же произошло на самом деле, я нашел этот пост, который спас меня:

https://medium.com/asos-techblog/what-you-didnt-know-about-arrays-in-kotlin-d3b20337e4

И самая важная часть заключается в том, что:

Kotlin сравнивает ссылки массива, а не содержимое. В классе Java Arrays.equals () используется для проверки содержимого, а не ссылки. Поскольку мы создали здесь два массива, они имеют разные ссылки.

Итак, если ваши классы данных содержат Array, вам придется переопределить equals или изменить его на List, иначе equals не будет работать правильно.

Надеюсь, это сэкономит хотя бы один день для кого-то :)

...