April 14, 2005

...Learn TDD with Codemanship

Constructors & Correctness

One kind of public method that's often overlooked when writing unit tests are constructors. Some developers are pretty lacksadaisy about how they write them, and many developers don't seem to fully understand what constructors are for.

If I ask a developer "what is a constructor for?", the typical response is "to run code when an object is created" or "to initialise an object". But why would we need to do that? Why can't we just create the object and set its properties afterwards?

Consider this example:



If the multiplicity of publisher with respect to every Book is exactly 1, then what does that tell us about the lifecycle of every Book? Correct, immediately after a Book is created, it must have a reference to exactly one Publisher.

If we wrote the code:

class Book {

private Publisher publisher;

}

And then instantiated a Book like this:

Book book = new Book();

The we would break the rule in our model that every Book has exactly 1 publisher. (ie, book.getPublisher() == null).

How do we solve this problem? One answer might be to create a Publisher by default:


class Book {

private Publisher publisher = new Publisher();
}


The problem with this approach is that we would create a brand new Publisher for every book published, which is a nonsense. The publisher most likely existed before the book, so we need a constructor in which we can pass a reference to the publisher:


class Book {

private Publisher publisher;

public Book(Publisher publisher){

this.publisher = publisher;
}
}


And, if our constructor is now doing something important, it would be a good idea to write a unit test to show that it works.


public void testBookConstructor(){

Publisher publisher = new Publisher();
Book book = new Book(publisher);

assertEquals(publisher, book.getPublisher());
}


So, the reason we need constructors is to ensure that objects don't break their rules immediately after they've been created. And when rules are involved, tests should never be far behind (indeed, if you're a fan of test-driven development like I am, then the tests should be right out in front!)

TEST YOUR CONSTRUCTORS!!!






Posted 15 years, 10 months ago on April 14, 2005