When I write code, one of my big concerns is how will I test it. I’ve learned that when I see a static method, it is going to make things more complicated than I would like. However, resolving that isn’t usually too difficult. Converting a string value into an Enum is a perfect example. Of course, parsing the string may succeed or fail and I need to know how my code will behave in either case, hence the reason for the unit tests.

In order to make unit testing a bit easier, I wrote a simple class to help out. Basically, this class “wraps” Enum.TryParse() and of course, implements and interface. I’m also using some simple generics to make the casting a little prettier. Since I used an interface, I can now using MOQ, RhinoMocks, or any other framework to mock my dependency and control how it behaves.

You may note that I didn’t call the methods Parse. Instead, I used the name Adapt. That is just a naming convention of my current project so it made sense to be consistent. Feel free to rename this as you wish :)

Here is the interface:

public interface IStringToEnumAdapter
{
     T Adapt<T>(string value) where T: struct;
     bool TryAdapt<T>(string value, out T? result) where T : struct;
}

You’ll probably notice that my generic constraint is struct. That is because you can’t use Enum as a generic constraint. So struct is the best I’ve got to work with. And considering we are doing parsing here, if you pass any other stuct in, it is going to fail on the parse anyway. So I think it is pretty safe.

Here is the implementation:

public class StringToEnumAdapter : IStringToEnumAdapter
{
    public T Adapt<T>(string value) where T : struct
    {
        T result;
        
        bool success = Enum.TryParse(value, true, out result);
 
        if (success)
            return result;
 
        throw new InvalidEnumArgumentException(string.Format("{0} could not be converted to {1}", value, typeof(T).Name));
    }
 
    public bool TryAdapt<T>(string value, out T? result) where T : struct
    {
        T parsedValue;
        bool success = Enum.TryParse(value, true, out parsedValue);
 
        result = success ? parsedValue : (T?)null;
 
        return success;
    }
}

Guess what? It isn’t all that complicated right? If you are getting into testing, you’ll soon find out that simple steps like this make life a lot easier.

Click here to download the class and unit tests for it too.

One thought on “Unit Testable Enum Parsing with C#

  1. I’m in the habit of wrapping statics as well for testability. It quickly becomes a must for TDD if you want to use Moq instead of a heavy-weight isolation framework like Moles. One thing that I think is unfortunate is the flak that you tend to get from people who favor a static/procedural approach (and who, as it turns out, tend not to write tests). It’s often them writing methods that I have to wrap, if it’s not something like File or your enum parsing example.

    Do you ever get a hard time from anyone for adding in "unnecessary" code that trades testability for complexity overhead?

    (By the way, your captcha doesn’t render in chrome on Win7, 32 bit for me).

    Reply

Leave a reply

required

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>