Unit Testing the Domain

This post is a follow-up to Are you valid?. Last time I tried to explain how the validation is done in our Domain project.

Peniko.Domain.Tests project contains Unit Tests for our Entity classes. The tests are written using NUnit library. Every entity class has its own test fixture. Below is a sample fixture for Category entity:

namespace BLDotNet.Peniko.Domain.Tests

{

    [TestFixture]

    public class CategoryFixture

    {

        private const int NameMaxLength = 50;

 

        private Category _category;

 

        [SetUp]

        public void SetUp()

        {

            _category = TestGlobals.GetValidCategory();

        }

 

        [Test]

        public void CanCreateCategory()

        {

            Assert.IsTrue(_category.IsValid);

            Assert.AreEqual("NewCategory", _category.Name);

        }

 

        [Test]

        public void CannotHaveNullName()

        {

            _category.Name = null;

            Assert.IsFalse(_category.IsValid);

        }

 

        [Test]

        public void CannotHaveEmptyName()

        {

            _category.Name = String.Empty;

            Assert.IsFalse(_category.IsValid);

        }

 

        [Test]

        public void CanHaveMaxLengthName()

        {

            _category.Name = new String('A', NameMaxLength);

            Assert.IsTrue(_category.IsValid);

        }

 

        [Test]

        public void CannotHaveTooBigName()

        {

            _category.Name = new String('A', NameMaxLength + 1);

            Assert.IsFalse(_category.IsValid);

        }

    }

}

And here is how the Category class looks like:

namespace BLDotNet.Peniko.Domain

{

    public class Category : Entity<Category>

    {

        [NotNullValidator]

        [StringLengthValidator(1, 50,

            MessageTemplateResourceName = "CategoryNameLength",

            MessageTemplateResourceType = typeof (Category))]

        public virtual string Name { get; set; }

    }

}

This case is very simple. Category has only one property - Name, apart from Id inherited from Entity class. The fixture only tests if the Category object can be created and if the validation is OK. Name property is tested for null and upper and lower length boundaries.

You'll notice that there is a SetUp() method that uses TestGlobals.GetValidCategory() method to create the Category to test. TestGlobals is a static class containing methods to create valid entities. We extracted entity creation from our test classes so we can reuse some entities as properties of other entities.

I.e. Project object has a Category property. TestGlobals.GetValidProject() calls TestGlobals.GetValidCategory() to assign to Category property. Some of you may ask now: Hey, what about mocking? Shouldn't you assign the mock Category to Project? Well, we are going one step at a time, no mocking frameworks learned yet :)

Most of our Domain tests looks like this. Some of the classes like OutputInvoiceDetail and InputInvoiceDetail have encapsulated calculations, so their tests are little more complicated, but not worth mentioning.

There are no Repository tests in Peniko.Domain.Tests project. Repositories are tested in separated DataLayer.Tests project. More on that later.


0 comments:

Post a Comment