Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NCover: Exclude unexecutable line of code from coverage

The switch statement in following code has a default clause that is required by the compiler and a nice safeguard, but which is never executed. After writing tests for everything else, there is no way I can (or should) test that one line. I don't care that I haven't covered that line with tests, but my TestDriven.net NCover code coverage report does show the untested line and this causes the class coverage to drop to 86%. Is there a way to let NCover exclude just this one line?

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();
        }
    }
}

My question is similar to this question, but none of the answers help in my specific situation.

like image 506
Daniel A.A. Pelsmaeker Avatar asked Jan 28 '26 12:01

Daniel A.A. Pelsmaeker


1 Answers

You can exercise it by casting integer value, which is not exists in OperandType enumeration to OperandType:

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

BTW I see nothing bad in 86% coverage

UPDATE: There is no benefit of using Contract here. You will get exception anyway if value is not supported by your method.

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();
        }
    }
}

And you should have defaultoption here, because if new value will be added to OperandType enum, your Contract will allow that value, but switch will not support new option.

UPDATE2: If you really need 100% coverage and Contract for this method, then use OperandType.None as default option:

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>";
        }
    }
}

And add to your test assertion about enum:

CollectionAssert.AreEquivalent(Enum.GetValues(typeof(OperandType)), 
                               new OperandType[] { OperandType.Int32,
                                                   OperandType.Int64, 
                                                   OperandType.None });
like image 86
Sergey Berezovskiy Avatar answered Jan 31 '26 02:01

Sergey Berezovskiy