I am planning to write an abstract class kind of thing for testing all my DTOs and DOMAIN objects. This class will take in templatable object (generic type)and use reflection to get the properties' types within and will assign some default values to the primitive types identified and later will assert these type values by accessing them. This way whenever my DTO tests inherit this class, most of the code is tested with one line of code written in the test. This is just an idea and want to know from you all if I am reinventing the wheel if something like this already exists? If there is a better way to test DTO's and domain object with less and resuable code.
3 Answers
I don't think that this is a good approach for testing Domain objects. By definition, these objects encapsulate data and related behavior, they suppose to be much more than just dumb data containers with getters and setters. You will have to hand write unit tests for these objects just like you hand-wrote the objects themselves. This is where you actually suppose to be spending time according to DDD.
Regarding DTOs you may want to look at this question.
2 Comments
My advice :
Don't unit test DTO's. These are just simple data structures with a bunch of getters and setters and no behavior. Getters and setters are too dumb to be tested (unless they encapsulate some kind of conditional logic which is rarely the case with DTO's).
Don't try to automate or genericize your domain object tests. I can't see how code that tests their behavior can be reused anyway since they all have a different behavior by definition.
Comments
Even though I think is kind of worthless to unit test DTOs, based on @Dmitry's answer I came up with this class:
[TestClass]
public class PeopleTest
{
[TestMethod]
public void OneObjectNull()
{
Person obj1 = null;
var obj2 = new Person
{
Id = "101",
Name = "George Waits",
Address = "Lake Palmer 10"
};
Assert.AreNotEqual(obj1, obj2);
Assert.AreNotEqual(obj2, obj1);
}
[TestMethod]
public void DeepEqual()
{
var obj1 = new Person
{
Id = "101",
Name = "George Waits",
Address = "Lake Palmer 10"
};
var peolpleList1 = new List<Person> { obj1 };
var peolpleList2 = new List<Person> { obj1 };
Assert.AreEqual(obj1, obj1);
CollectionAssert.AreEqual(peolpleList1, peolpleList2);
}
[TestMethod]
public void DeepNotEqual()
{
var obj1 = new Person
{
Id = "101",
Name = "George Waits",
Address = "Lake Palmer 10"
};
var obj2 = new Person
{
Id = "102",
Name = "Rachel Smith",
Address = "Lake Palmer 10"
};
var peolpleList1 = new List<Person> { obj1 };
var peolpleList2 = new List<Person> { obj2 };
Assert.AreNotEqual(peolpleList1, peolpleList2);
var group1 = new KeyValuePair<string, List<Person>>("group1", peolpleList1);
var group2 = new KeyValuePair<string, List<Person>>("group2", peolpleList2);
Assert.AreNotEqual(group1, group2);
}
[TestMethod]
public void PropertyPositive()
{
var obj1 = new Person
{
Id = "101",
Name = "George Waits",
Address = "Lake Palmer 10"
};
obj1.Address = "Parker av 101";
var obj2 = new Person
{
Id = "102",
Name = "Rachel Smith",
Address = "Lake Palmer 10"
};
obj1.Address = "Listener av 45";
Assert.AreNotEqual(obj1, obj2);
}
}
setmethods...maybe it's better use some library like project lombok to generate them if you feel the need to test them...