How to Unit Test a Missing Case in a Switch Statement

enumtest-coveragetesting

I often use enum types in my code with a switch to apply logic to each type. In these cases it's important that each enum has code implemented.

For example;

public enum eERROR
{
    REQUIRED,
    DUPLICATE,
    UNKNOWN,
    MISSING_VALUE
}

public void Error(eERROR pError)
{
    switch (pError)
    {
        case eERROR.REQUIRED:
            // ......
            return;
        case eERROR.DUPLICATE:
            // ......
            return;
        case eERROR.MISSING_VALUE:
            // ......
            return;
        case eERROR.UNKNOWN:
            // ......
            return;
    }

    throw new InvalidArgumentException("Unsupported error type");
}

At the bottom I've added an exception as a last resort check that a programmer remembered to add any new enum types to the switch statement. If a new type is added to eERROR the exception could be thrown if the code is not updated.

Here is my problem.

The above code generates unit test coverage of only 99% because I can not trigger the exception. I could add a generic unhandled to eERROR and call Error(eERROR.unhandled) just to get 100% coverage, but that feels like a hack to solve something that is not a problem just to get full coverage. I could remove the line but then I don't have the safety check.

Why is 99% a problem? because the code base is so large that any uncovered method doesn't move coverage to 98%. So I always see 99% and don't know if I missed a method or two.

How can I rewrite Error() so that all newly added enums that are not added to the switch will be caught somehow by the programmer, and also be covered by tests. Is there a way of doing it without added a dummy enum?

Best Answer

Depending on your language, you should just be able to pass in a garbage value to the Error constructor. Most languages just use integers for enum values. In pseudo-code:

e = new Error(eError -1)
>> InvalidArgumentException: Unsupported error type