the blog for developers

JUnit recipes: Work around static attributes in classes

Beware of the class loader. I recently had a major testing problem with some code because I didn’t take the (sometimes ugly) Java class loading mechanism into account. There was a small class where I wanted to unit test the calculateAge method.

class AgeCalculator {
    public int calculateAge(Person person) {
      ....
    }
}

So I dropped EasyMock into my project and mocked the person class. I was using jMock in the past and could live with methods as strings. With the new JMock 2 syntax this has changed. I still struggle with {{ in JMock expectations and so does my IDE. When IDEA learns to format JMock expectations, I’m back. For now I’m using EasyMock though, sometimes with JMock assertions from the excellent Hamcrest assertion library. Back to the problem at hand . The mock was passed into the AgeCalculator to calculate the age of the person. The problem was the Person class.

class Person {
  private static Configration conf =
    new DatabaseConfiguration("Person");
    ...
}

Even though I didn’t use the Person class, just a mock, the static attributes where initialized and the DatabaseConfiguration tried to load data from the backend. This happens whenever your classloader sees the Person type, even in an interface.

interface Calculator {
    public int calculateAge(Person person);
}

Using Calculator in mocks will initialize the static attributes in Person. Which contradicted the isolation principle of unit tests and also led to long startups of the database backend. This stopped my efforts to test the AgeCalculator. Time passed.

Then I stumbled upon JMockit. Others have too. The friendly and supportive developers of JMockit have helped (thanks Rogerio) and with a simple line I was saved:

Mockit.redefineMethods(
  DatabaseConfiguration.class,
  MockDatabaseConfiguration.class
);

Constructs like the above with static attributes should never be created in the first place (hello all those people who propagate static inialized attributes for singletons to avoid synchronized). But if you have such code in your legay base, JMockit to the rescue.

Thanks for listening.

You can leave a Reply here. Of course, you should follow me on twitter here.

You can share this post!
Do you want to tell others about this article? Use the social bookmark icons to submit this artice to the service of your choice. Thanks.

About the author: Stephan Schmidt has more than 15 years of internet technology experience and 10 years experience in agile. He was head of development, consultant and CTO and is a speaker, author and blog writer. He specializes in organizing and optimizing software development helping companies by increasing productivity with lean software development and agile methodologies. Want to know more? All views are only his own.
Leave a reply.

Comments

[...] JUnit recipes: Work around static attributes in classes- Some hip advice here. [...]

Thomas Hawk

I am curious as to why you need an AgeCalculator class with a calculateAge method. I, of course, am not familiar with your code, but it seems to me calculateAge should be a method in the Person class.

stephan

@Thomas: The names have been changed to protect the innocent :-)

But as a side node, I’ve been moving further and further away from OO to a data holder object and service programming style. Any business logik inside of objects looks now suspicious to me. I think services like AgeCalculator are much more versatile and exchangable.

Qrilka

I think the problem is in using concrete classes not interfaces. So If Person would be just an interface you won’t have such situation. Concrete classes enlarge code coherence and create problems like the one you’ve mentioned.

stephan

@Qrilka: Yes you’re right. I most often use interfaces instead of classes, but this was legacy code which couldn’t easily be changed.

But although most people would use interfaces for services (storage, view), I seldom see people using interfaces for business objects like Person.

stephan

Thinking about that again, as Qrilka said, the problem (in this case) arises from interfaces depending on classes. So interfaces should only depend on other interfaces, not on concrete classes.

Thnks for your comment.
I have to work around with Legacy Code a lot. Client usually do not allow us to change the design. So sometime I have to use stubbed classes or jMockit.

Leave a Reply

What people wrote somewhere else:

Additional comments powered by BackType

Guide to CodeMonkeyism

Over the last 4 years I wrote many articles on this blog. To make it easier for you to find the relevant ones, I've organized them into topics.

Top 10

6 reasons why my VC funded startup did fail

Go Ahead: Next Generation Java Programming Style

Java Interview questions: Write a String Reverser

The dark side of NoSQL

7 Bad Signs not to Work for a Software Company or Startup

Is Java dead?

Scala vs. Clojure

Never, never, never use String in Java

No future for functional programming in 2008 – Scala, F# and Nu

Clojure vs Scala, Part 2

Java Developer

Is Java Dead?

Go Ahead: Next Generation Java Programming Style

Be careful with magical code

All variables in Java must be final

Never, never, never use String in Java

Bending Java: More readable code with methods that do nothing?

NoSQL Guy

NoSQL: The Dawn of Polyglot Persistence

The dark side of NoSQL

Essential storage tradeoff: Simple Reads vs. Simple Writes

Sharding destroys the goals of your relational database

The unholy legacy of databases

Startup/CTO

Development Dream Teams

6 reasons why my VC funded startup did fail

American vs. European style of Software Development

12 Things to Reduce Your Lead Time and Time to Market

The high cost of overhead when working in parallel

Essential storage tradeoff: Simple Reads vs. Simple Writes

Job Seeker

Another Good (Java) Interview Question

7 Bad Signs not to Work for a Software Company or Startup

Java Interview questions: Write a String Reverser (and use Recursion!)

Java Interview questions: Multiple Inheritance

As a Manager: What I value in developers

Top 10 Tips (+1) to Get a Pay Raise

Agilist

What Developers Need to Know About Agile

5 Practices Better to Change in Your Scrum Implementation

Scrum is not about engineering practices

ScrumMaster and ZenMaster: The joke of certification

What is Trans-Scrum?