Should you Unit Test simple properties?

I would have to say no. If that doesn't work, you have bigger problems. I know I don't. Now some will argue that having the code alone would make sure the test failed if the property was removed, for example. But I'd put money on the fact that if the property were removed, the unit test code would get removed in the refactor, so it wouldn't matter.


I would suggest that you absolutely should.

  • What is an auto-property today may end up having a backing field put against it tomorrow, and not by you...

  • The argument that "you're just testing the compiler or the framework" is a bit of a strawman imho; what you're doing when you test an auto-property is, from the perspective of the caller, testing the public "interface" of your class. The caller has no idea if this is an auto property with a framework-generated backing store, or if there is a million lines of complex code in the getter/setter. Therefore the caller is testing the contract implied by the property - that if you put X into the box, you can get X back later on.

  • Therefore it behooves us to include a test since we are testing the behaviour of our own code and not the behaviour of the compiler.

  • A test like this takes maybe a minute to write, so it's not exactly burdensome; and you can easily enough create a T4 template that will auto-generate these tests for you with a bit of reflection. I'm actually working on such a tool at the moment to save our team some drudgery

  • If you're doing pure TDD then it forces you to stop for a moment and consider if having an auto public property is even the best thing to do (hint: it's often not!)

  • Wouldn't you rather have an up-front regression test so that when the FNG does something like this:


//24-SEP-2013::FNG - put backing field for ConnectionString as we're now doing constructor injection of it
public string ConnectionString
{
   {get { return _connectionString; } }
   {set {_connectionString="foo"; } }//FNG: I'll change this later on, I'm in a hurry
}

///snip

public MyDBClass(string connectionString)
{
   ConnectionString=connectionString;
}

You instantly know that they broke something?

If the above seems contrived for a simple string property I have personally seen a situation where an auto-property was refactored by someone who thought they were being oh so clever and wanted to change it from an instance member to a wrapper around a static class member (representing a database connection as it happens, the resons for the change are not important).

Of course that same very clever person completely forgot to tell anyone else that they needed to call a magic function to initialise this static member.

This caused the application to compile and ship to a customer whereupon it promptly failed. Not a huge deal, but it cost several hours of support's time==money.... That muppet was me, by the way!

EDIT: as per various conversations on this thread, I wanted to point out that a test for a read-write property is ridiculously simple:

[TestMethod]
public void PropertyFoo_StoresCorrectly()
{
   var sut = new MyClass();
   sut.Foo = "hello";
   Assert.AreEqual("hello", sut.Foo, "Oops...");
}

edit: And you can even do it in one line as per Mark Seeman's Autofixture

I would submit that if you find you have such a large number of public properties as to make writing 3 lines like the above a chore for each one, then you should be questioning your design; If you rely on another test to indicate a problem with this property then either

  • The test is actually testing this property, or
  • You will spend more time verifying that this other test is failing because the property is incorrect (via debugger, etc) than you would have spent typing in the above code
  • If some other test allows you to instantly tell that the property is at fault, it's not a unit test!

edit (again!): As pointed out in the comments, and rightly so, things like generated DTO models and the like are probably exceptions to the above because they are just dumb old buckets for shifting data somewhere else, plus since a tool created them, it's generally pointless to test them.

/EDIT

Ultimately "It depends" is probably the real answer, with the caveat that the best "default" disposition to be the "always do it" approach, with exceptions to that taken on an informed, case by case basis.


Are you adhering to strict TDD practices or not?

If yes then you absolutely should write tests on public getters and setters, otherwise how will you know if you've implemented them correctly?

If no, you still probably should write the tests. Though the implementation is trivial today, it is not guaranteed to remain so, and without a test covering the functionality of a simple get/set operation, when a future change to implementation breaks an invariant of "setting property Foo with a value Bar results in the getter for property Foo returning value Bar" the unit tests will continue to pass. The test itself is also trivially implemented, yet guards against future change.


Generally, no. A unit test should be used to test for the functionality of a unit. You should unit test methods on a class, not individual, automatic properties (unless you are overriding the getter or setter with custom behaviour).

You know that assigning a string value to an automatic string property will work if you get the syntax and setter value correct as that is a part of the language specification. If you do not do this then you will get a runtime error to point out your flaw.

Unit tests should be designed to test for logical errors in code rather than something the compiler would catch anyway.

EDIT: As per my conversation with the author of the accepted answer for this question I would like to add the following.

I can appreciate that TDD purists would say you need to test automatic properties. But, as a business applications developer I need to weigh up, reasonably the amount of time I could spend writing and performing tests for 'trivial' code such as automatic properties compared to how long it would reasonably take to fix an issue that could arise from not testing. In personal experience most bugs that arise from changing trivial code are trivial to fix 99% of the time. For that reason I would say the positives of only unit testing non-language specification functionality outweigh the negatives.

If you work in a fast paced, business environment which uses a TDD approach then part of the workflow for that team should be to only test code that needs testing, basically any custom code. Should someone go into your class and change the behavior of an automatic property, it is their responsibility to set up a unit test for it at that point.