Home > .NET, Testing > Enums and inheritance in .Net

Enums and inheritance in .Net

In one of my current projects I had the following code (I simplified the code a bit):

public string ConnectionString
{
	get
	{
		switch(this.Importer)
		{
			case Importer.SqlServer:
				return "Server=localhost;Database=Northwind";
			case Importer.SqlServerOleDb:
				return"Provider=SQLOLEDB;Data Source=localhost;Initial Catalog=Northwind";
			default:
				throw new NotSupportedException(
				string.Format("Importer {0} is not supported yet.", this.Importer));
		}
	}
}

After running the code coverage tool (dotCover from JetBrains) I received the following picture:

CodeCoverage

First idea

So, my code was clear and understandable, but obviously not fully tested (green: covered by tests, red: not covered). I asked me the question, how could I test the rest of the method.

My idea was to extend the enum:

[TestFixture]
public class ConfigurationTest
{
        #region Test methods
        #endregion

        private enum TestImporter : Importer
        {
            Test
        }
}

But the compiler and the ReSharper weren’t happy with my idea: “Type byte, sbyte, short, ushort, int, uint, long, or ulong expected”. I was surprised at this error: Why it isn’t possible to make a subclass of an enum?

I found the explanation first on stackoverflow and then in the specification of the Common Language Infrastructure (CLI, section 8.5.2):

It shall derive from System.Enum

An enum in .Net has to derive directly from enum, it isn’t possible to inherit from another enum. So, the enums in .Net don’t follow the open/closed principle (OCP). With the OCP you don’t modify a class when you want to extend it, you inherit from it and do the extensions in the subclass:

Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.

Second idea

My code wasn’t tested and is it really not possible to test it? Well, it is possible, but the code isn’t very nice (hard cast):

 [Test]
[ExpectedException(typeof(NotSupportedException))]
public void TestConnectionString_With_Invalid_Enum()
{
	// Arrange
	this.Configuration.Importer = (Importer) 100;

	// Act
	string strConnectionstring = this.Configuration.ConnectionString;
}

Conclusion

I my current decision is to leave the code as it is. The reasons were the following:

  • Readability is very important
  • You have to use default or a return value, otherwise the code will not compile
  • I want that my tests will fail when I extend the enum and test the new value. So it is easier to find the places where I have to adjust something (but it smells like shotgun surgery…)
  • The code is testable, but you have to create an invalid enum value by hard casting an integer (and that is ugly)

I’m not really convinced with my current decision, but I could live with it. How would you design the code? Are there any better ways to test the code?

If you like this, follow me on twitter…

Share
Categories: .NET, Testing Tags: