views:

106

answers:

1

I've been reading a lot on TDD over the past few months and decided to jump in and try it out with an easy example, I'm just not sure I'm testing for the right things in practice. Here the tests for a custom Data Annotation for validating emails:

using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace MembershipTest.Tests
{
    [TestClass]
    public class CustomDataAnnotationsTest
    {
        [TestMethod]
        public void CustomDataAnnotations_Email_ReturnTrueIfNull()
        {
            // Arrange
            EmailAttribute attribute = new EmailAttribute();

            // Act
            bool result = attribute.IsValid(null);

            // Assert
            Assert.AreEqual(true, result);
        }

        [TestMethod]
        public void CustomDataAnnotations_Email_ReturnFalseIfInvalid()
        {
            // Arrange
            EmailAttribute attribute = new EmailAttribute();

            // Act
            bool result = attribute.IsValid("()[]\\;:,<>@example.com");

            // Assert
            Assert.AreEqual(false, result);
        }

        [TestMethod]
        public void CustomDataAnnotations_Email_ReturnTrueIfValid()
        {
            // Arrange
            EmailAttribute attribute = new EmailAttribute();

            // Act
            bool result = attribute.IsValid("[email protected]");

            // Assert
            Assert.AreEqual(true, result);
        }
    }
}

And here is the subsequent code written for the test:

using System;
using System.ComponentModel.DataAnnotations;
using System.Net.Mail;

public class EmailAttribute : ValidationAttribute
{
    public override bool IsValid(object value)
    {
        //Let RequiredAttribute validate whether the value is required or not.
        if (value == null)
        {
            return true;
        }

        //Check to see if System.Net.Mail can send to the address.
        try
        {
            var i = new MailAddress(value.ToString());
        }
        catch (Exception)
        {
            return false;
        }

        return true;
    }

}

All tests failed initially and then succeeded after writing the code, but are the tests appropriately written? Too much, or too little? I know this is a very simple example, but I want to make sure I'm on the right track before moving on to more complicated things.

+5  A: 

I think you are on the right track. At this point I would suggest some refactoring in your tests. Since you are using

EmailAttribute attribute = new EmailAttribute();

in every test. I would suggest creating TestInitialize() and TestCleanup() methods. The TestInitialize would new EmailAttribute and the TestCleanup would null the object out. This is just a matter of preference. Like this

private EmailAttribute _attribute;

[TestInitialize]
public void TestInitialize()
{
  _attribute = new EmailAttribute
}

[TestCleanup]
public void TestCleanup()
{
  _attribute = null;
}
mpenrow
Great point there, going with SetUp/TearDown is definitely a good practice :)
wintermute
Your point is very valid, but using the Visual Studio unit testing tools, I think those attributes should be `TestInitialize` and `TestCleanup` respectively (the ones you have used are for NUnit) :D
Cocowalla
Thanks Cocowalla. I have changed the attribute names.
mpenrow
Thanks, mpenrow!
Graham