I have a bunch of assemblies with near 100% test coverage but I often run into a situation like in the example below. I cannot test the default switch case, which is there to guard against future bugs where I add more items to the enum but forget to update the switch statement to support new items.
I would like to be able to either find a pattern where I can eliminate that "untestable" code, test it or mark that line of code (but not the entire method) to be excluded by the coverage analysis.
It may sound silly but I do not want to assume the default case will never happen, and I do not want to bundle the default case with one that already exist. I want the exception to be thrown when I create such bugs. Which will happen sooner or later.
I use DotCover to calculate coverage at the moment.
Note: This is just example code but I think it illustrates a fairly common pattern.
public class Tester { private enum StuffToDo { Swim = 0, Bike, Run } public void DoSomeRandomStuff() { var random = new Random(); DoStuff((StuffToDo)random.Next(3)); } private void DoStuff(StuffToDo stuff) { switch (stuff) { case StuffToDo.Swim: break; case StuffToDo.Bike: break; case StuffToDo.Run: break; default: // How do I test or exclude this line from coverage? throw new ArgumentOutOfRangeException("stuff"); } } }
The easiest way to exclude code from code coverage analysis is to use ExcludeFromCodeCoverage attribute. This attribute tells tooling that class or some of its members are not planned to be covered with tests. EditFormModel class shown above can be left out from code coverage by simply adding the attribute.
To calculate the code coverage percentage, simply use the following formula: Code Coverage Percentage = (Number of lines of code executed by a testing algorithm/Total number of lines of code in a system component) * 100.
To do this, edit your workspace settings to set salesforcedx-vscode-core. retrieve-test-code-coverage to true and then run your Apex tests. You can now see the code coverage in the Output panel, which shows the coverage percentage per Apex Class and Apex Trigger and lines that were not covered by the test run results.
Code coverage checks for private methods too. Generally, there are 2 scenarios where private method gets called. For this case, you will need to call the public method in your tests and cover the underlying private method directly and satisfying the condition from your tests.
Private methods are always candidates to be extracted into its own classes. Especially, if they hold complex logic, like yours do. I suggest you make a StuffDoer
class with the DoStuff()
as a public method and inject it into your Tester
class. Then you have:
DoStuff()
method, reachable by testsDoSomeRandomStuff()
method that can be tested with a mock instead of relying on the outcome of DoStuff()
, thus making it a true unit test.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With