次のようなコードがあるとします。
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列挙型の拡張を処理するためのセキュリティ対策がないため、引用符で囲まれたコードが未定義の動作に影響を与える可能性があります。NorthWest
SouthEast
SouthWest
この件に関していくつか質問があります。
プログラマーはここでセキュリティ対策を実装する必要があります。例:
default: throw new InvalidArgumentException("Unsupported enum value!");
この問題は単体テストでテストする必要がありますか?
// Naïve implementation, for example purposes only [ExpectedException(typeof(InvalidArgumentException))] [Test] void SomeTestMethod() { SomeFunction((Direction)-1); }
もしそうなら、そのような種類のテストをどのように自動化しますか(たとえば、この列挙型の他のすべての値とは異なる順序値を見つけ、列挙型のバッキングタイプを考慮に入れるなど)?
この問題は静的コード分析中に検証する必要がありますか?どのツールがそのような情報を提供できますか?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; } } } }
この一般的な問題に対する一般的なアプローチはありますか?例えば。リフレクションを使用してC#で高度なテストメソッドを記述できるかもしれませんが、C ++では、C#や他の高級言語よりも、このような潜在的なコード整合性違反を特定するのがはるかに困難です。
ユニットテスト中にチェックする必要があるかどうかを尋ねるのはなぜですか?これは、私が知る限り、メソッドが想定(文書化)されているとおりに動作するかどうかを単体テストで検証するためです。この場合、4つの列挙型要素のいずれかを受け入れることになっていますが、実際にそれを行うため、すべてのテストに合格する必要があります。潜在的な問題をチェックすることは、ユニットテストプロセスの問題ではないように思えます。単体テストで発生する可能性のあるすべての可能性を検証したい場合は、おそらく3行のコードメソッドに対して何百ものテストを作成することになります。
一方、誰かが列挙型に別の値を追加することを決定したときに、この方法が深刻な問題を引き起こさないことを確認するのは、(使用済みリソースの観点から)非常に安価な方法のようです。