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!