More Time Saved By Unit Tests

So I’ve been meaning to make a fix in one of my projects for a while, and I haven’t touched the code in over a year, so of course I have to go back and really get back up to speed with the code. The change was for the Datavalve project and it was to include support for passing in collections and using in SQL Statements, so now you can use something like :

provider.addRestriction("item.statusCode in (:param)", stateCodeList);

This will cause the list of codes to be expanded into an in SQL statement including checking to exclude null items, and as usual, the restriction is not included if the code list is null or contains only null items.

So I have two problems, the first is getting back up to speed on my code, figuring out where the make the change, and making it. The second is making sure my code changes don’t break anything thats currently working.

For the first problem, I decide to create the unit tests first so I can verify that the change does as expected. Obviously, the tests fail initially, but by looking at the code executed by the tests, I can start to pick out places where I need to start looking to add the new code. After all, tests measure the correctness of the state after the code has been executed. What better place to start looking than seeing what code the test executes. After finding the method that I need to change, I make my code changes and run my tests. All my original tests pass with flying colors, but my new test fails. I take a peek and sure enough I left off the last line of code to add the built object to a list. I put it in, and I have all my tests up and running.

All in all, I’ve made a large change to some sizable (12K+ LOC) code that I haven’t seen in over a year, verified that the change works and that it hasn’t impacted any other code. Not bad for an hour.

2 thoughts on “More Time Saved By Unit Tests

  1. Welcome back.

    I’m experiencing DataValve, which mixing with Seam-3.1.0.CR1 and PrimeFaces-3.0.RC1 in GlassFish-3.1.2.b13.

    I have some ideas:

    1. To make doUpdate() abstract in AbstractEntityHome.
    then we can implement doUpdate() in JpaEntityHome.

    public class JpaEntityHome extends AbstractEntityHome {

    @Override
    protected void doUpdate() {
    getEntityManager().merge(getEntity());
    }
    // …
    }

    2. To change EntityHome as the following:

    public interface EntityHome<T, PK> {

    T getEntity();
    void setEntity(T entity);
    PK getId();
    void setId(PK id);
    // …
    }

    3. In AbstractQueryDataProvider, to deprecate addRestrictionStr() and modify isValidTestValue() as the following:

    protected boolean isValidTestValue(Object obj) {
    // …
    if (obj instanceof String) {
    String s = (String) obj;
    return s.length() != 0;
    }
    //…
    }

    4. How about add method delete() in EntityHome?

    5. update the link “Download Now” in http://www.andygibson.net/blog/projects/datavalve/

    DataValve fans should download the last source from https://github.com/andygibson/datavalve instead of http://kenai.com/projects/datavalve/downloads

  2. Hey There,

    Thanks for the notice on the links, I’ve already fixed them. The entity home stuff is still very much in development, but since I didn’t know anyone was using it, I haven’t been developing it much.

    As for the addRestrictionStr, the reason for the two is so you still have the option of running queries against null strings. I’m thinking of changing it though to use the one method, but with flags to trim and exclude zero length strings which will be the default, but you can turn it off. I’ll have to have a think about it, because some of these things get evaluated at query time (i.e. EL Expressions) when the user is not in control, so I’ll have to have a look and see what is done there.

    Cheers,

    Andy