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:ディレクティブの欠如に注意してください。ここで、後で誰かがその列挙型にさらに4つの値を追加したとします:NorthEast、、、。このような場合、Directions列挙型の拡張を処理するためのセキュリティ対策がないため、引用符で囲まれたコードが未定義の動作に影響を与える可能性があります。NorthWestSouthEastSouthWest

この件に関していくつか質問があります。

  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#や他の高級言語よりも、このような潜在的なコード整合性違反を特定するのがはるかに困難です。


ユニットテスト中にチェックする必要があるかどうかを尋ねるのはなぜですか?これは、私が知る限り、メソッドが想定(文書化)されているとおりに動作するかどうかを単体テストで検証するためです。この場合、4つの列挙型要素のいずれかを受け入れることになっていますが、実際にそれを行うため、すべてのテストに合格する必要があります。潜在的な問題をチェックすることは、ユニットテストプロセスの問題ではないように思えます。単体テストで発生する可能性のあるすべての可能性を検証したい場合は、おそらく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 に答える