When you can’t avoid an out parameter

We all know its a good idea to avoid using out variables in Java. In almost every case the code can be split up to avoid the situation. Its bad semantics because when reading the code its not obvious which object passed, if any will get mutated.  So the reader is forced to open the method to find out what it does. In Robert C Martin’s Clean Code Book he calls this forcing a double take, and suggests some ways to avoid the problem.  Rarely you find a case where you can’t avoid it, or to be more accurate, avoiding it leads to worse problems.

Take a look at this interface.  If I find this populate method, I am likely to have to open implementations.  I don’t know if it populates one map from the other or both maps.

import java.util.Map;

public interface NastyPopulator {

void populate(Map<String, String> driver, Map<String, String> driverHolder);

}

The problem is the semantics of map are that you can read from maps or you can write to them.  I think this is a slightly better approach below.

I have used ImmutableMap.Builder.  The semantics of this are that it is used to build things.  I will call build() on the object later to get a map.  Next its an ImmutableMap.  So not only am I declaring that the two parameters are likely to be used to build something, that thing will ultimately be Immutable so in effect the signature declares that I am not expected to make modifications later.  Finally the method name is unambiguous buildMaps, which pretty much says what its going to do.

import com.google.common.collect.ImmutableMap;

public interface LessNastyPopulator {

void buildMaps(ImmutableMap.Builder<String, String>  driver, ImmutableMap.Builder<String, String> driverHolder);

}

Feels like a stronger declaration to me. If ImmutableMap is awkward you could define your own static builder and pass that in, at least your still declaring up front, that this method is builds the two maps. If the method is reading from one map and building others, how about passing an iterator and a builder?

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

Test anti-patterns project, contributors wanted!

Take a look at the following test class.  I deliberately wrote this poor quality test, so that I could show how easy it is to re-factor it to a better one. I was driven by having seen lots of such poor tests and to be honest I don’t want to see another of its ilk again. I might write a test like this myself, but I would never leave it like this. Its part finished. Its littered with cut and paste, poorly named methods and hard coded values. It’s a bit like a surgeon performing an operation and not sewing up the hole! I would go as far as to say that leaving tests in this state is unprofessional. There is no excuse as most of the lessons of good naming and code re-use have been written down a long time back. More lately in Clean Code by Robert C. Martin. I just don’t understand why people still write rubbish like this! Possibly because they are allowed to get away with it! Note that the test provides 100% coverage of the implementation class, but its not enough to stop there.

Have a read over the class, and then move on to read the steps to re-factor to better patterns. I have several designs here that focus on the setup stage of a test. As your tests get more complex you will find the patterns here support ever increasing complexity. In an Agile project you might move from one system to the next as the requirements ramp up. Then once you see where I am heading, I lay down a challenge.

Test anti-patterns project, contributors wanted!

If you have a Test Anti-Pattern that you would like to showcase. Check out my code from gitHub, add the new example and examples of how to re-factor the code. Blog it to your own blog with a reference to this page, or drop a comment. If we get enough I will setup a page with an index to all the blogs.

The code can be forked out with git from gitHub http://github.com/mhgit/TerribleJavaTestingMadeGood. It should be an easy start. Its a full maven project with a small dependency set and maven site reports already built in for test coverage. Its fully open source with the Apache 2.0 license. Once you have your new example, tell me about it by adding a comment to this page, and following the git forking instructions for making a git pull available.

Continue reading

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

Neat multiset in google collections API

This good thing was so small that I almost did not bother to blog it

But the devil is in the detail so here it is anyway.

I have this multi threaded application. One of the problems with integration testing it is, you can’t guarantee the order that messages will be written to a stream. So during the test I have to go to some trouble to split and order the lines written out. If I don’t do this the test fails sometimes. It depends on which thread writes first. The output though is correct, order is not important. Not exactly rocket science.

Here is the method I was using to massage the string.

 public List<String> getSortedLines(String expectedString) {

        String[] splitExpectedResultLines = expectedString.toString().split("\n");
        List<String> resultLines = new ArrayList<String>();
        for (String messageLine : resultLines) {
            resultLines.add(messageLine);
        }

        Collections.sort(resultLines);
        return resultLines;
    }

There is nothing particularly wrong with the method. It takes a string, splits it into lines, loads a List, sorts and returns it. Thus when its used in an assertion later the expected and actual lists are the same.

With google collections its just three lines! The HashMultiset is designed to be used in equals methods. Its equal even if the order of the elements in collections being compared is different. From the API documentation: An extension of Collection that may contain duplicate values like a List, yet has order-independent equality like a Set. One typical use for a multiset is to represent a histogram.

Its possible to use the HashMultiSet.create static factory method, passing in an Iterable. i.e a Collection. So from the original code, both the loop and the Collections.sort are no longer required.

   public HashMultiset<String> getOrderAgnosticCollection(String expectedString) {

        String[] splitExpectedResultLines = expectedString.toString().split("\n");
        Iterable<String> resultLines = Arrays.asList(splitExpectedResultLines);
        HashMultiset<String> orderAgnosticResultLines =
                                              HashMultiset.create(resultLines);

        return orderAgnosticResultLines;
    }

If there was something that performed the split, but returned an Iterable the method would be perfect! ;-)

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

Testing java equals and hashcode methods

Write a java test for the equals method! What is the point in wasting time on that?

All good java programmers know the equals and hashcode methods are vitally important. I have seen some unpredictable behavior through bugs in these two methods.

If your about to click away to something more interesting fine, but first read my page with an example equals bug. See if you can spot the problem before I show the solution.

Writing a test for the equals method

Writing a test for equals is so easy its tedious. Which is perhaps why so much code gets written and not tested. First from the javadoc what are the specifications for a good equals and hashcode implementations?

Continue reading

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)