Recently, I had to come up with a unit test to test a certain functionality for each value of an enum. Let's say the enum is something like this:
public enum Number { One = 1, Two, Three, Four, Five, Six }
The unit test I wrote first was:
[Theory] [InlineData(Number.One)] [InlineData(Number.Two)] [InlineData(Number.Three)] [InlineData(Number.Four)] [InlineData(Number.Five)] [InlineData(Number.Six)] public void TestNumber(Number number) { Assert.Equal(true, (Convert.ToInt32(number) > 0)); }
Though it worked fine for the given situation, I wanted a better way to do this so that that even if more values were added to the enum in the future, the test would still work without needing changes.
Fortunately, xUnit has ways to parameterize tests with data from members of a class using MemberData attribute (There is good material online about these attributes, eg: here).
The solution using MemberData is:
public static IEnumerable<object[]> enumValues() { foreach (var number in Enum.GetValues(typeof(Number))) { yield return new object[] { number }; } } [Theory] [MemberData("enumValues")] public void TestNumberGeneric(Number number) { Assert.Equal(true, (Convert.ToInt32(number) > 0)); }
With C# 6.0 and above, instead of using MemberData("enumValues"), we can use the nameof operator like MemberData(nameof(enumValues)) and avoid hard-coding the method name.
Nice blog.
ReplyDelete