views:

38

answers:

2

What's the best way to unit test the Serialization of an Exception class like this:

[Serializable]
public abstract class TankBaseException : Exception
{
    public TankBaseException() : base() { }

    public TankBaseException(string message) : base(message) { }

    public TankBaseException(string message, Exception innerException) : base(message, innerException) { }

    public TankBaseException(SerializationInfo info, StreamingContext context)
        : base(info, context)
    {
        this.timeStamp = info.GetDateTime(String.Format("{0}.TimeStamp", this.GetType().Name));
        this.machineName = info.GetString(String.Format("{0}.MachineName", this.GetType().Name));
    }

    public override void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        base.GetObjectData(info, context);

        string typeName = this.GetType().Name;

        info.AddValue(String.Format("{0}.TimeStamp", typeName), this.timeStamp, this.timeStamp.GetType());
        info.AddValue(String.Format("{0}.MachineName", typeName), this.machineName, this.machineName.GetType());
    }

    public override string Message
    {
        get
        {
            return String.Format("{0} (Machine Name: {1}; TimeStamp: {2}",
                base.Message, this.MachineName, this.TimeStamp);
        }
    }

    private readonly string machineName = Environment.MachineName;
    public string MachineName
    {
        get { return this.machineName; }
    }

    private readonly DateTime timeStamp = DateTime.Now;
    public DateTime TimeStamp
    {
        get { return this.timeStamp; }
    }
}

It's a contrived example, to keep the sample code here to a minimum. It'll be part of a hierarchy of exception classes. I'll derive from it in my unit test project to test the base class hierarchy. Also, I'll test any derived classes that have their own additional functionality.

The question is about the best way to test the serializable aspects of the class in a way that conforms to Osherove's 'pillars of good tests' - that they're:

  • trustworthy
  • maintainable
  • readable

(or any other set of guidelines for doing unit testing).

Or, to put it another way, how can I test whilst introducing the least number of confounding variables?

A: 

You can't. This is an abstract class.

Your only option is to have a subclass of it and unit test.

I am wondering why is it an abstract class? It does not have an abstract method or property.

Aliostad
Okay, yes, I asked for that one! I'll edit my post. Serialization is the issue.
SGarratt
I've clarified that, now, I hope.
SGarratt
A: 

You could use the Exception contract verifier of Gallio/MbUnit.

Contract verifiers are configurable built-in test suites for well known code patterns. MbUnit has in particular a dedicated contract verifier for testing custom exception types, which includes serialization tests as well.

[TestFixture]
public class SampleExceptionTest
{
  [VerifyContract]
  public readonly IContract ExceptionTests = new ExceptionContract<SampleException>()
  {
    ImplementsSerialization = true,
  };
}
Yann Trevin