3

次のコードのswitchステートメントにはdefault、コンパイラーに必要な句と優れたセーフガードがありますが、実行されることはありません。他のすべてのテストを作成した後、その1行をテストする方法はありません(またはテストする必要があります)。その行をテストでカバーしていなくてもかまいませんが、TestDriven.net NCoverコードカバレッジレポートにはテストされていない行が表示されるため、クラスカバレッジは86%に低下します。NCoverにこの1行だけを除外させる方法はありますか?

public static class OperandTypeExtensions
{
    public static string ToShortName(this OperandType type)
    {
        #region Contract
        Contract.Requires<InvalidEnumArgumentException>(Enum.IsDefined(typeof(OperandType), type));
        #endregion

        switch (type)
        {
            case OperandType.None: return "<none>";
            case OperandType.Int32: return "i32";
            case OperandType.Int64: return "i64";
            default:
                throw new NotSupportedException();
        }
    }
}

私の質問はこの質問に似ていますが、どの答えも私の特定の状況では役に立ちません。

4

2 に答える 2

3

OperandType 列挙に存在しない整数値を OperandType にキャストすることで実行できます。

Assert.Throws<InvalidEnumArgumentException>(delegate { ((OperandType)Int32.MaxValue).ToShortName(); } );

ところで、86% のカバレッジで悪いことは何もありません

更新: ここで使用するメリットはありませんContract。値がメソッドでサポートされていない場合は、とにかく例外が発生します。

public static class OperandTypeExtensions
{
    public static string ToShortName(this OperandType type)
    {
        switch (type)
        {
            case OperandType.None: return "<none>";
            case OperandType.Int32: return "i32";
            case OperandType.Int64: return "i64";
            default:
                throw new NotSupportedException();
        }
    }
}

新しい値が列挙型にdefault追加される場合、その値は許可されますが、スイッチは新しいオプションをサポートしないため、ここにオプションが必要です。OperandTypeContract

UPDATE2: このメソッドに 100% のカバレッジとコントラクトが本当に必要な場合は、デフォルト オプションとして OperandType.None を使用します。

public static class OperandTypeExtensions
{
    public static string ToShortName(this OperandType type)
    {
        Contract.Requires<InvalidEnumArgumentException>(Enum.IsDefined(typeof(OperandType), type));

        switch (type)
        {
            case OperandType.Int32: return "i32";
            case OperandType.Int64: return "i64";
            default:
                return "<none>";
        }
    }
}

そして、列挙型に関するテスト アサーションに追加します。

CollectionAssert.AreEquivalent(Enum.GetValues(typeof(OperandType)), 
                               new OperandType[] { OperandType.Int32,
                                                   OperandType.Int64, 
                                                   OperandType.None });
于 2012-05-15T15:15:58.500 に答える
-1

また、% ではなく、すべてのソース ファイルを 100% に到達させたいと考えていましたが、コード カバレッジ ツールを実行して誤検出を検出するたびにすべてのクラスを二重にチェックすることは避けたいと考えていました。

この場合と IMO では、関数が公開されている場合は、同様のものでテストする必要があることを意味します。

Assert.Throws<NotSupportedException>( OperandTypeExtensions.ToShortName() );

その他起こりうるケース

通常、throwsやが含まれる関数Debug.Assertがプライベートの場合、より大きな問題が発生します。その場合、テストで回線に到達できない場合があります。または、 にカプセル化できませんAssert.Throws

すべての行が確実に実行されるようにする唯一の方法を見つけました。理想的ではなく、非常に醜い、私はそれを無効にするためにそのようなコメント注釈を好んだでしょう。ただし、C# では機能しませんでした。

private string ToShortName(this OperandType type)
{
    var result = "";
    switch (type)
    {
        case OperandType.Int32: result = "i32";
        case OperandType.Int64: result = "i64";
    }
    Debug.Assert(result != "", "Invalid type.");
    return result;
}

このソリューションでは、ソース コードで空の文字列を返す前に (デバッグで) ブレークし、コード カバレッジは Debug.Assert 行を実行済みとして表示します。

PSただし、注釈やコードブロックを具体的に無効にする何かなど、より良い解決策があるかどうかを知りたいです。

于 2014-01-23T22:50:09.587 に答える