Zombies
Zombies

Reputation: 25902

How to unit test code with very few units

How can I write unit tests for existing and already implemented code which has taken a procedural implementation as opposed to an OOP implementation. We are using Java/Spring, however there are not a lot of different beans for the different concerns, which are all mixed into one large class per piece of of major functionality. (EG: we have classes/beans for each batch job, for our DAOs and a few util type beans and that's it).

Just to give some more details, these major classes which need to be tested are about 1k-2k lines of code, and the only dependency injection/OOP they use is DAOs and some odd utilities. They have about 1 public method which they implement for an interface they all share.

Upvotes: 9

Views: 122

Answers (2)

Guillaume
Guillaume

Reputation: 22822

Just to add some other considerations to the great answer from Tomasz Nurkiewicz (which I second completely):

  • Sometimes (well, always really), it's useful to write at least one encapsulating "acceptance test" before starting the refactoring (if there is no existing one). Once it passes, you can then start refactoring and make sure you haven't broken anything "important" at each step. Before starting an important refactoring task, it's very useful to have such a harness to keep you sane :)

  • Refactoring is not just a technical task: you don't only want to break big classes into smaller ones and extract code to methods. You want to think about what your code is supposed to do, in terms of objects, and move to a better design. It will make your life easier in the long run.

  • As a rule of thumb, I try to have no class above 80-100 lines of code (and ideally lower than 50). Of course there are exceptions, but when it gets bigger, I usually try to refactor separate concerns into collaborator objects that get injected into the main class. It keeps the code readable and easy to test.

Upvotes: 1

Tomasz Nurkiewicz
Tomasz Nurkiewicz

Reputation: 340883

Start by refactoring. Modern IDEs will allow you to refactor safely without breaking or changing the code semantics. But you have to do this consciously and be smart.

Start from "outer" classes that are not dependencies of any other classes.

First step is to extract as many methods as you can. Typically when you find a huge method with lots of blank lines/comments separating blocks of code they are good candidates for extractions. Also loops, nested conditionals, long switches, etc. should be considered.

Once you have plethora of well named methods look around and try to group them by moving them up and down. If some method are closely coupled and logically dependent, extract them to a separate class. IDE will assist you.

This process can be repeated on every layer and multiple times. Aim for small, cohesive classes, if you cannot name it (e.g. you have to use "And" to express what method/class is doing), extract further.

Of course you can test it as-is - I guess every possible execution path can be reached with different set of input parameters. But this will be a nightmare to debug.

Upvotes: 7

Related Questions