4

假设有一段代码:

enum Directions
{
    North,
    South,
    East,
    West
}

// (...)

switch (dir)
{
    case North : // Do sth
    case South : // Do sth
    case East : // Do sth
    case West : // Do sth
}

特别注意缺乏default:指导。现在假设,后来有人向该枚举添加了另外四个值:NorthEast, NorthWest, SouthEast, SouthWest。在这种情况下,引用的代码很可能会影响未定义的行为,因为没有安全措施来处理对 Directions 枚举类型的可能扩展。

我有一些关于这个问题的问题。

  1. 程序员是否应在此处实施安全措施,例如:

    default: throw new InvalidArgumentException("Unsupported enum value!");
    
  2. 这个问题是否应该在单元测试中进行测试?

    // Naïve implementation, for example purposes only
    [ExpectedException(typeof(InvalidArgumentException))]
    [Test]
    void SomeTestMethod()
    {
        SomeFunction((Direction)-1);
    }
    

    如果是这样,您将如何自动化此类测试(例如,找到与此枚举中的所有其他值不同的序数值,考虑枚举支持类型等)?

  3. 静态代码分析时是否应该验证这件事?哪个工具可以提供这样的信息?我在 VS 2012 Pro 中编写了简单的概念证明,运行代码分析,但 IDE 报告说“未检测到代码分析问题”。

    编码:

    namespace ManagedConsoleSketchbook
    {
        class Program
        {
            enum MyEnum
            {
                One,
                Two,
                Three
            }
    
            static void Main(string[] args)
            {
                MyEnum e = MyEnum.One;
    
                switch (e)
                {
                    case MyEnum.One:
                        break;
                    case MyEnum.Two:
                        break;
                }
            }
        }
    }
    
  4. 有没有解决这个普遍问题的通用方法?例如。也许我可以使用反射在 C# 中编写复杂的测试方法,但在 C++ 中,与 C# 或其他高级语言相比,确定这种潜在的代码完整性漏洞要困难得多。


为什么我要问是否应该在单元测试期间检查它?这是因为 - 据我所知 - 单元测试应验证,如果方法的行为与预期(记录)到. 在这种情况下,它应该接受四个枚举元素中的任何一个,并且它确实做到了,所以所有测试都应该通过。在我看来,检查潜在问题似乎不是单元测试过程的关注点。如果我想验证单元测试中潜在问题的所有可能性,我可能最终会为 3 行代码方法编写数百个测试。

另一方面,当有人决定向枚举添加另一个值时,它似乎是一种非常便宜的(就花费的资源而言)方法来确保该方法不会引起任何严重的问题。

4

3 回答 3

2

1:是的,我经常这样做。

2:是的。我要补充一点:

[ExpectedException(typeof(InvalidArgumentException))]
[Test]
void SomeTestMethod()
{
    Direction testValue = (Direction)-1;
    Assert.IsFalse(Enum.IsDefined(typeof(Direction), testValue));
    SomeFunction((Direction)-1);
}
于 2013-01-15T14:25:52.470 回答
2

这个问题实际上是在 VS-2012 中处理的。请注意,默认情况下禁用此测试。

启用警告后,您可以指示 Vs 将此特定警告视为错误。

于 2013-01-15T14:23:08.963 回答
1
  1. 是的
  2. 这将是理想的测试。
  3. 我不知道有什么工具可以做到这一点。
  4. 最简单的方法是总是有一个默认子句。当默认值不应该做任何事情时,请编写如下内容:

    default:
        // No action required
        break;
    

    这样,您的程序员至少会考虑剩余的项目(如果有的话)。

于 2013-01-15T14:26:01.377 回答