Too simple to break

07 April 2006

Every now and then, as is my wont, I get to thinking about unit testing, most often in terms of test-driven development. However, I have been known to countenance unit tests outside of that methodology, but you have to ply me with a good meal and an excellent bottle of wine and turn off the tape recorder first, though.

Many times developers write a class using simple properties; that is, properties which have the standard one-line get and set blocks. Using VS2005 this is simple enough with the prop snippet expansion (and is even easier with CodeRush, of course).

class Foo {
  public int Age {
    get { return age; }
    set { age = value; }

Now the question arises: is it worth writing a unit test for this property? The simplest would probably be this code.

public void ShouldReadChangedAge() {
  Foo foo = new Foo();
  foo.Age = 49;
  Assert.AreEqual(49, foo.Age);

But is this worth it? I would argue that, no, it isn't. In fact, there is also a school of thought that says that writing this kind of property is not worth while either ("just use a public field, dude"), but I shall address that question later on.

The code that implements this property is, in essence, "too simple to break". Instead, we should concentrate our testing efforts on code that is more intricate and more likely to break, such as code with higher cyclomatic complexity. Writing bad code for a property with a one-line getter and setter is pretty hard to do without being obvious about it, and you'll notice the bug pretty quickly too. (The only real example I can think of from the top of my head is to use the wrong backing field.)

Note that I'm not saying that it is wrong to write such a test. All I'm saying is that you'll get more bang for the unit-testing buck by writing tests for a more complex method (or property for that matter). (Examples of properties that should be tested: one whose getter invokes a calculation to get the value to return, or one whose setter involves several side-effects such as updating other fields or performing other calculations.)

I'm sure a unit-testing purist would undoubtedly say that not having a test for this property means that the property is untested and therefore prone to failure. This is quite right, but note that using the tools we have at our disposal, you must really want to write bad code to get this kind of property wrong. Also, unit testing, no matter how hard we try, is never guaranteed to uncover all our bugs.

What we try and do with unit testing is to use our judgment and resources and time to discover and fix bugs as soon as possible in the project's lifetime. Bugs discovered early are almost free to fix. Bugs discovered later are much harder to fix and cost a lot more in terms of time and resources. So we try and balance our time and resources writing production code with the code that tests it. Too much time spent writing unit tests can be just as bad as too much time spent writing production code. In the first case, we are gaining greater confidence in our code at the expense of much greater schedule time, in the second case we are getting the real code written faster at the expense of having a nasty bug (or bugs) possibly to be discovered by our customers. We have to learn to balance this more tests versus less scheduled time trade-off.

In essence, I'd say don't bother testing code that's too simple to break. But certainly be prepared to defend your assertion that the code you're not testing really is too simple to break.

Free DevExpress Products - Get Your Copy Today

The following free DevExpress product offers remain available. Should you have any questions about the free offers below, please submit a ticket via the DevExpress Support Center at your convenience. We'll be happy to follow-up.
No Comments

Please login or register to post comments.