Let's say you have a function that takes in an enum value or uses an enum value fetched from some other source (a private class field, a property of an object passed in, etc.). If a value is added to that enum, how do you write a unit test for that function so that it catches that something has to be added to your function to support that enum (or at minimum, you need to check to see if you have to add anything to the function to support it).
I've already discussed how to put in a check for making sure that your function will bomb if an unsupported enum value is passed in in my "Unit Testing Switch Statements" post. This takes it one step further to ensure that your unit tests catch the bombing of this function if a new enum value is added so that this bombing doesn't occur in production or even in QA's testing.
Below I have an example of this situation. I apologize for the crude example but it gets the point across on how to test this situation.
public enum CalculatorOperations
{
Add,
Subtract
}
public static class Calculator
{
public static int PerformOperation(CalculatorOperations operation, int a, int b)
{
Check.Invariant(operation == CalculatorOperations.Add ||
operation == CalculatorOperations.Subtract,
string.Format("{0} is not a supported CalculatorOperations value.", operation));
int result = 0;
switch(operation)
{
case CalculatorOperations.Add:
result = a + b;
break;
case CalculatorOperations.Subtract:
result = a - b;
break;
}
return result;
}
}
[TestFixture]
public class Calculator_Tester
{
[Test(Description = "Tests for unsupported CalculatorOptions values.")]
public void Test01()
{
Type enumType = typeof (CalculatorOperations);
foreach (FieldInfo field in enumType.GetFields(BindingFlags.Static | BindingFlags.Public))
{
CalculatorOperations operation = (CalculatorOperations) field.GetValue(null);
Calculator.PerformOperation(operation, 1, 1);
}
}
}Now if I add Multiply and Divide to the CalculatorOperations enum, my unit test will fail because Calculator.PerformOperation will throw an exception on the unsupported value.
Remember, "do nothing" is still an intended behavior. So even if you don't explicitly use an enum value in a function, you need to have it in your "supported enum values" list to ensure that that value allows the function to perform the way it is intended to. The added benefit of this technique is that it also catches scenarios that you haven't tested for. Even if PerformOperation is going to return 0 (do nothing in the switch statement) when Multiply or Divide are passed in, then you need to write unit tests for those values and then add those enum values to the function's "supported enum values" list.
0 comments:
Post a Comment