Posts
1150
Comments
891
Trackbacks
1
DDD-Lite: Unit-testing Constructors

update: updated the first test so that the constructor is doing something, since that was kind of the point.

When I was first learning about TDD, the guy I knew who was actually practicing it unit tested his object constructors.  Obviously, it was a different domain, but I vaguely recall that it looked something like this:

[TestMethod]
        public void can_create_an_item()
        {
            Item i = new Item(“Name”);
            i.ShouldNotBeNull();
            i.Name.ShouldEqual("Name");
    }

Being the helpful kind of guy that I am, I made fun of him for it.  This is where I asked him “do you unit test that Int increments properly?”  He’s normally a well-rounded, easy-going, good-natured kind of guy.  He didn’t think it was funny.

Fast forward a couple of months.  I was putting together a small domain model for some trivial app, and so, of course, was creating classes through the time-honored tradition of copy and paste.  God being Just, I forgot to fix up a copy and paste procedure and so one of my object construction had a bug in it.  Naturally (especially since I gave him a hard time about it, I had to), I told him about it and his response was something like “In your face for the mother-f%&king win!”

Anyway, as I put together this new system, I come back to the question of whether to unit-test object constructors.  I still feel, well, a bit dirty, or stupid, doing it.  Am I really going to test whether I can assign a string to a string property?  Really?  TDD of the strict variety says I have to.  Well, okay.  For now.

digression: besides the fact that it just feels silly, what I don’t like about testing object constructors is that as I go down the road and add new properties and such, I will have to remember to add them to the constructor tests.  This is an obvious area for potential screw-ups.  This is something that code generation can help with (yes, I know, I know, code generation is bad/flawed/whatever.  You’re wrong, so bite me), as repetitive code should ideally never be hand-written.  Refactor project for later.   Eventually, there will be Validation tied into the whole thing, so that a constructor test will fail if a required property is added, but I haven’t decided how to do the validation piece yet, so I’m YAGNI-ing it for now.

But, there is another area where it makes a little more sense.  I’m ripping off ObjectBuilder type syntax to add a little bit of fluency.  So, something like this:

[TestMethod]
        public void can_create_an_item_using_fluent_syntax()
        {
            Item i = new Item().WithName("Name");
            i.Name.ShouldEqual("Name");

        }

I feel better about this sort of test, because I am testing a ‘fluent’ (is it fluent?  is it a good idea?  I’ve decided to use it, so that is good enough for me right now) syntax on top of the normal object constructor stuff.

In the long run, I am pretty certain that I will decide not to manually write normal object constructor tests.  But, I am going to stick with it for now.  The immediate downside is that I need to write 2 tests, one with normal syntax, one with ‘fluent’ syntax.  For now, I’ll eat the three minutes it takes to do that.

posted on Tuesday, December 16, 2008 7:18 PM Print
Comments
Gravatar
# re: DDD-Lite: Unit-testing Constructors
Robin Clowers
12/16/2008 7:42 PM
Normally when practicing TDD, you want to keep your constructor free of any logic. This helps keep you objects easy to construct in tests. As far as bugs like assigning a constructor argument to the wrong instance variable, that would be caught by tests on the functionality of the class. So in that scenario, I don't see a need to test the constructor. Your fluent builder syntax should probably be covered by other tests too, although only you can know that for sure.
Gravatar
# re: DDD-Lite: Unit-testing Constructors
Casey
12/17/2008 2:51 AM
You only unit test logic, so if a constructor has logic you test it.

All other tests will use the constructor, so it will be covered, but part of the purpose of tests is to help track down bugs and inadvertent changes, so often it helps to have a constructor test just to help pin down here the bug is.

For the sake of 5 lines of code at the beginning of a test class, put it in anyway. An if you have multiple paths through construction (throwing exceptions on null parameters for example), test those paths too.
Gravatar
# re: DDD-Lite: Unit-testing Constructors
rscot231
12/17/2008 8:41 AM
I believe I am being somewhat misquoted here.

Short version:
In general, I prefer to keep logix out of constructors. But when I do include it, I test it.

Also, it was more like "IN YOUR FACE YOU ROUND-BACON LOVER!"

Long version:

Prefer to keep logix out of your constructor. Instead prefer simply assigning instance variables from injected parameters.

If you absolutely must include logix in your constructor, test them.

Logix in the constructor should be an exceptional case, but should be tested **on their own** if they exist. This is because a test should be testing only one thing. When your test fails, you immediately have an indicator of where your system is doing something wrong.

I'm not going to get into all of the problems associated with logix in constructors, because I'm saving those for if I ever start a blog.

Post Comment

Title *
Name *
Email
Url
Comment *  
Please add 7 and 7 and type the answer here: