Winter has gone, spring has come. Let’s integrate it.

In the “At the red-green-refactor carousel – implementing conversion unit” post I described how I have developed basic functionalities for conversion unit. I also mentioned that there is no Spring Framework integration and why I decided to implement CU in that way. In the following post, I’m going to show you this mystic integration process.

I would like to remind you that all of the sources are available in my Github repository. Moreover, in the README file, you can find short project description with its main assumptions.

Wait, wait, wait…

I started to create classes without thinking. In a little hurry, I wrote a simple test and then controller class.

The next step was to refactor the controller and try to process whole password object:

Every time I ran the test I got 400 response and information about test failure. I spent almost 2 hours on looking for a working solution and guessing why the test logic is no able to convert password object into JSON properly. After that time, I realized that I had been trying to do too much on one “step”. I asked myself: “Why don’t you start with a simple object and then increase complexity?”. The answer was: “Damn, that’s true, it’s how TDD works. Let’s do it”. I replaced Password with String.

When I had a working test then I replaced String with CharacterElement, CharacterElement with GestureElement, GestureElement with List<PasswordElement> and finally, List<PasswordElement> with Password.

Much to my surprise, I had fully working controller template within 30 minutes. Now we can compare – 2h hours of guessing and trying vs. 30 minutes of conscious code writing.

New layer is required

During the implementation process, I met some problems connected with insufficient interfaces, e.g. lack of default constructor, missing getter/setter. As I mentioned in one of the previous posts I want to separate, as much as I can, framework related interfaces from business interfaces.

That is the reason why I’ve created simple Data Transfer Layer which consists of multiple Data Transfer Objects. DTOs have all of the essential methods – constructors, getters, setters.

Now I want to introduce you simple example showing why I’ve made a decision for such separation.

CharacterElement is considered as incorrect when it doesn’t have character element set. If I had written constructor without parameters, I would allow creating a  CharacterElement object with incorrect state. Even more, if I had allowed to do it, a user would pass this object into the conversion mechanism which could try to convert corrupted object. Disaster guaranteed.

CharacterElementDTO allows you to create an object without a character set but this object is useless in the context of e.g. password resolver.To pass it to the conversion service, you have to convert DTO into a regular element beforehand. It means that converter is responsible for validating object’s state. Additionally, validation logic is placed in one particular place.

Abstract type

A Password object consists of a list of PasswordElement. For Password object, it is completely transparent if it is a character or a gesture. As you know if a function gets a PasswordElement, it doesn’t know its real representation. Moreover, the frontend module is also able to distinguish those types.

In order to avoid “chains of ifs” I had to find the solution how to make the controller capable of handling conversion and how to recognize a correct type.

It comes as a surprise that Jackson module has everything I needed.

Basing on the “type” property the application can determine if a processed object is a character or a gesture.

Conversion service

The introduction of the DTL has one consequence. Every time the application handles request it has to convert request’s content from DTO type. For this purpose, I decided to extend ConversionService possibilities and implement custom Converters. Following converters have been added:

  • CharacterElementDTOConverter
  • GestureElementDTOConverter
  • PasswordDTOConverter
  • PointDTOConverter

All of the details connected with extending ConversionService I covered in the “Konwersja obiektów z użyciem ConversionService” post. Unfortunately, it is written in Polish so stay tuned for the English version.

Parametrized tests

During the development, I decided to write some parametrized tests. It turned out to be very fast and easy. Everything I had to do was to prepare sets of data which will be treated as separate test cases, write test logic and provide some setup for WebApplicationContext. With tests written that way, I don’t duplicate testing logic and I’m able to add next test cases with ease. Parametrized tests are also handy if a business logic changes frequently because you are supposed to make changes only in one place. For more details check AksesiApplicationTestParametrized class.

Lesson learned

The most important thing that I’ve learned during this iteration was to write unit tests incrementally and without a hurry. By making small steps I provide working solution faster and without any weird hacks inside.

 

The next post will be less technical but still programming-related. I think it will be useful not only for programmers but also for everyone who is not interested in programming.

You may also like