Tuesday, July 3, 2007

Unit testing setters and getters for Java base types

Yesterday we took a look at some "stock" unit tests for Java bean-style setters and getters, where the underlying property was an object. The tests for properties with base types will be similar, but slightly different. One nice thing about the object tests are that they can use the assertSame assertion (essentially that two objects are == each other) to make sure that the setters/getters do exactly what you thought they would. It's a little different with base types, because these must be compared by value and not by reference. For example, suppose we had implemented a setter for an integer like this (maybe as a stub):

protected int n;
public void setN(int newN) {
  /* no-op */;
}
Now, what if your unit test looked like this:
public void testSetsOwnNOnSetN() {
  int n = 0;
  underTest.setN(n);
  assertEquals(n, underTest.n);
}
It would pass (eek)! In the object cases, we were creating a new mock object and then making sure that object got put in there. Now, we can't necessarily tell. And there's always some chance that the setter is doing something funky, or that it got stubbed out with just the wrong value (incidentally, this is a good reason why it's better practice to throw an IllegalStateException("Not implemented") for an unimplemented method rather than just return something of the right type). So, I think the easy solution here is to use java.util.Random and generate a random non-zero value to use in the tests. Even better, generate two different values, and do:
underTest.n = rand1;
underTest.setN(rand2);
assertEquals(rand2, underTest.n);
Probably for a boolean you just want to exhaustively check the four cases of (previous_state, new_state). That's it for today. We'll be back on Thursday after the July 4th holiday, perhaps with a full-on listing of the unit tests for all the base types.

1 comments:

comment system said...

Nice to see this approach. There have been unlimited times we have been using getters and setters in our Java classes but never have I thought about implementing any unit cases for getter and setter. Would really want to use it in my next Unit case.