views:

295

answers:

5

So standard Agile philosophy would recommend making your domain classes simple POCOs which are Persisted using a separate proxy layer via data access objects (like NHibernate does it). It also recommends getting as high unit test coverage as possible.

Does it make any sense to write tests for these simple POCO objects? Say I have a class which looks like this:

public class Container {
 public int ContainerId { get; set;}
 public string Name { get; set;}
 public IList<Item> Contents { get; set;}
}

What useful unit tests can I write for this?

+1  A: 

this is just my habit, and I am by no means the end-all-be-all to this, but I don't write tests until I have a constructor that actually does something (i.e. set default values).

You need to test your own code, not the language. You're guaranteed whenever you new Container() you're going to get a new Container. And, if you do mess up that step the compiler is going to catch it.

Kyle West
A: 

I like to think of a unit test as "calling out" a unit of intent.

The only intents expressed by your code are getters and setters; being part of the language, we assume those work.

No other intent is expressed, and thus no tests are required.

I would suggest removing the setter from the Contents property, however. Collection properties should be read-only.

Bryan Watts
never heard that before, but makes sense
George Mauer
+3  A: 

Actually, I think if you started writing tests for this code before you wrote the class, your implementation would be different. For example, you'd probably end up writing a constructor that initializes your collection so that you can reference it without having to check for null each time. I think it's probably a good practice to write the tests even if you don't think you need them. Often in writing the tests you find that there are a lot of assumptions that you've made that wouldn't have been addressed with your first code attempt.

For example, could the ContainerId ever be less than zero? Would it be an error to attempt to set it to a negative value? Should the collection be initialized by a constructor, i.e., should classes that use this container class have to check for null before accessing or do you want to guarantee the collection will never be null, though it might be empty?

That said, I typically apply some sanity to the process. For example, if I know that the constructor is internally scoped and objects are only created by a Factory class. I'll test the factory methods to ensure that they always produce legal objects, but not necessarily test the container class itself.

I guess the bottom line, for me anyway, is to assume that classes need tests, attempt to write them, and only omit them when I can't think of a meaningful test to write.

tvanfosson
+2  A: 

Typically a value object like that doesn't need to have its own tests. You'll get coverage from the classes that use it to actually do something.

The unit tests are designed to test behavior. No behavior? No need for a test.

Jeffrey Fredrick
A: 

I'd argue that this isn't even an object - and object is defined by its behavior, and this class doesn't have any. It's a pure data container. It's ok to have those, too - and they typically don't need any tests -, but Beware that you don't end up with an Anemic Domain Model. Using Test Driven Development would "force" you to first think about the behavior of your classes, and might be a good exercise.

Ilja Preuß