TDD Anti-Pattern: The Nullifier

December 29th, 2006 by James Carr

Lately I’ve been encountering quite a bad smell in a few unit tests I’ve seen (and even a few I’ve written): tests that only contain assertNull and assertNotNull. Essentially, the tests will verify that a method call returns something besides null, but doesn’t verify the value of the object returned.

I initially noticed this when one of my co-workers (who has also read my TDD Anti-Patten list) called me over the other day to show me what he felt was the reason there was quite a few bugs in one of the classes I had written. As we looked through the unit test a partner and I had written, I noticed that we had started out small with each feature (which is a good thing!), checking that the methods worked and returned a value, but rather than following up and testing the actual behavior, we had instead opted to just move forward to the next feature, resulting in a unit test with 300 lines of null/not null assertions.

Avoidance is pretty simple… just follow up on small/simple test cases with test cases that really do test the behavior of the feature. In fact, if null/not null assertions don’t really provide any value and are really simply artifacts of small first steps, I believe it would be better to simply remove them and only keep the later tests that provide value by testing behavior, not language level semantics like nil values. However, if value can be gained from a null/not null assertion, then keep it! Just weigh the benefits. ;)

Using Value Objects in Fitnesse With Nested Tables

December 3rd, 2006 by James Carr

Today I discovered something rather cool while playing with FitLibrary. Not only can you just pass primitive types to fixtures, you can also pass in value objects as well (at least in DoFixture) by using nested tables.

Nested tables work pretty interesting, and I couldn’t really find much documentation on it outside of a scant bit on the fitnesse mailing list and what I was able to figure out by fiddling around. To start things off, I thought I’d show off an example I have while putting together an Email Fixture for checking emails in a mail box. In this particular case, this is a portion that sends an email for the fit test for the fixture. Below is what the table with the nested table looks like:

To do this, you have to assign the nested table to a variable, then simply reference the variable within the table.


!define inner_table (|subject|This is a test|
|type|text/plain|
|body|some content|
)

|Email Accessor|
|connect to|*****|using password|test123|on server|example.com|
|check for|0|messages with subject|This is a test|
|send email|${inner_table}|
|disconnect|

The code for the EmailAccessor is simple… simply extend a DoFixture and have a method called sendEmail which takes an argument (in our case, of type EmailMessage):


public class EmailAccessor extends DoFixture{
   ...
   public void sendEmail(EmailMessage message){
      this.box.send(message);
   }

Now, how does the inner table map to the domain object it represents? The values in the first column map to setters, with the values in the second or further columns as parameters. Below is the relevant method signatures for EmailMessage:


public class EmailMessage{
	...
	public void setType(String type){
	...
	}
	public void setSubject(String subject){
	...
	}
	public void setBody(String body){
	...
	}
}

You can even use nested tables within nested tables to map to domain objets for arguments to other domain objects, although it may look a bit complicated at that point. It worked well on a personal project I did some time ago however as the documentation for a standard I was implementing contained a set of nested tables that outlined the message format. ;)

Let it Snow…

December 1st, 2006 by James Carr

Last night it started snowing pretty hard, with forcasts that we could get 6 or so inches. When I decided to go to sleep, I looked out the window and saw it snowing lightly, ,with grass still poking out through the snow… no big deal. Just a normal light snowfall.

Well, to my surprise, I awoke to discover a staggering 2 feet of snow on the ground… my car was buried (along with most of the cars in my apartment complex) in large snow drifts. I went out to my car to see how difficult it would be to get out, and the snow was up to my waste. No luck getting out.

So, a fun filled snow day, and with the drifts it looks like I won’t be getting my car out anytime soon. ;)