Ensuring valid enums with testing in .Net Core

I wrote a while back on a previous blog, that I wanted to make 100% certain that the enums that I was setting up were set up correctly. One of the issues I encountered was not being able to run the tests within a testing framework, which I have since managed resolved and have gotten the tests running with XUnit.

See the test snippet below, but basically, we have 3 tests:

  • Normal Enums must not have duplicate values
  • Flagged Enums must always have a 0 value
  • Normal Enums must not have a 0 value

Using some of the magic of reflection we are able to test for all these.

     using System;
     using System.Collections.Generic;
     using System.Linq;
     using System.Reflection;
     using Xunit;
     using Xunit.Abstractions;

     namespace BusinessLogic.Tests.Enums
     {
         public class EnumTest
         {
             private readonly ITestOutputHelper output;

             public EnumTest(ITestOutputHelper output)
             {
                 this.output = output;
             }

             private Type[] GetEnums()
             {
                 return Assembly.GetAssembly(typeof(BusinessLogic.Enums.OrganisationType))
                     .GetTypes()
                     .Where(t => t.IsEnum && t.IsPublic).ToArray();
             }

             [Fact]
             public void GetRawConstantValue_NonFlaggedEnums_DoNotHaveDuplicateValues()
             {
                 var enums = GetEnums();

                 foreach (var e in enums)
                 {
                     var attributes = e.GetCustomAttributes();
                     var fields = e.GetFields();
                     if (attributes.Any(x => x.GetType().Name == "FlagsAttribute"))
                     {
                         continue;
                     }
                     else
                     {
                         var values = new List<int>();
                         foreach (var field in fields)
                         {
                             if (!field.IsSpecialName)
                             {
                                 var val = (int) field.GetRawConstantValue();
                                 values.Add(val);
                             }
                         }

                         var originalLength = values.Count();
                         Assert.Equal(originalLength, values.Distinct().Count());
                     }
                 }
             }

             [Fact]
             public void GetRawConstantValue_FlaggedEnums_AlwaysHaveAZeroValue()
             {
                 var enums = GetEnums();

                 foreach (var e in enums)
                 {
                     var attributes = e.GetCustomAttributes();
                     var fields = e.GetFields();
                     if (attributes.Any(x => x.GetType().Name == "FlagsAttribute"))
                     {
                         var values = new List<int>();
                         foreach (var field in fields)
                         {
                             if (!field.IsSpecialName)
                             {
                                 var val = (int) field.GetRawConstantValue();
                                 var fieldAttributes = field.GetCustomAttributes();
                                 values.Add(val);
                             }
                         }

                         Assert.Contains(values, x => x == 0);
                         Assert.True(values.Count(x => x == 0) == 1);
                     }
                     else
                     {
                         continue;
                     }
                 }
             }

             [Fact]
             public void NonFlaggedEnums_MustNotHave0()
             {
                 var enums = GetEnums();

                 foreach (var e in enums)
                 {
                     var attributes = e.GetCustomAttributes();
                     var fields = e.GetFields();
                     if (attributes.Any(x => x.GetType().Name == "FlagsAttribute"))
                     {
                         continue;
                     }
                     else
                     {
                         var values = new Dictionary<int, string>();
                         foreach (var field in fields)
                         {
                             if (!field.IsSpecialName)
                             {
                                 var val = (int)field.GetRawConstantValue();
                                 var fieldAttributes = field.GetCustomAttributes();
                                 values.Add(val, e.Name);
                             }
                         }
                         Assert.DoesNotContain(values, x => x.Key == 0);
                     }
                 }
             }
         }
     }

And that’s all there is to it!