vendredi 30 novembre 2018

integration testing, comparing JPA entities

Consider you are doing some integration testing, you are storing some bigger entity into db, and then read it back and would like to compare it. Obviously it has some associations as well, but that's just a cherry on top of very unpleasant cake. How do you compare those entities? I saw lot of incorrect ideas and feel, that this has to be written manually. How you guys do that?

Issues:

  • you cannot use equals/hashcode: these are for natural Id.
  • you cannot use subclass with fixed equals, as that would test different class and can give wrong results when persisting data as data are handled differently in persistence context.
  • lot of fields: you don't want to type all comparisons by hand. You want reflection.
  • @Temporal annotations: you cannot use trivial "reflection equals" approaches, because @Temporal(TIMESTAMP) java.util.Date <> java.sql.Date
  • associations: typical entity you would like to have properly tested will have several associations, thus tool/approach ideally should support deep comparison. Also cycles in object graph can ruin the fun.

Best solution what I found:

  • don't use transmogrifying data types (like Date) in JPA entities.
  • all associations should be initialized in entity, because null <> empty list.
  • calculate externaly toString via say ReflectionToStringBuilder, and compare those. Reason for that is to allow entity to have its toString, tests should not depend that someone does not change something. Theoretically, toString can be deep, but commons recursive toStringStyle includes object identifier, which ruins it.
  • I though, that I could use json format to string, but commons support that only for shallow toString, Jackson (without further instructions on entity) fails on cycles over associations

Alternative solution would be actually declaring subclasses with generated id (say lombok) and use some automatic mapping tool (say remondis mapper), with option to overcome differences in Dates/collections.

But I'm listening. Does anyone posses better solution?





Aucun commentaire:

Enregistrer un commentaire