How to cover method return statement in Apex Class?
You have unreachable statements, and your code is overly complicated. You should remove your use of switch
statements entirely.
I recommend you simplify the logic for getting quarter to something like the below:
public Integer getQuarterNumber(Integer month)
{
return 1 + (Integer)Math.floor((month-1)/3);
}
public String getQuarterName(Integer month)
{
return 'Q' + getQuarterNumber(month);
}
This code should be very easy to cover.
As for getting the name of the month, I would use standard Datetime formatting and keep this logic out of your own code. Something like below would be very easy to use and cover, and should update based on the running user's language:
String getMonthName(Integer month)
{
return Datetime.newInstance(2000, month, 15, 0, 0, 0).format('MMMM');
}
If you want to guarantee the month name is in English, a more classic approach will give you what you want without forcing you to hit every single execution path in your test. Use a Map
.
static final Map<Integer, String> monthNames = new Map<Integer, String>
{
1 => 'January',
2 => 'February',
// etc
};
public static String getMonthName(Integer month)
{
return monthNames.get(month);
}
One advantage to using a map over a list here is you do not have to worry about bound checking or exceptions based on invalid input. You will simply get a name of null
if you pass in 15 as your month number, for example.
The golden rule of unit testing is that you only gain coverage for code that is executed as part of a unit test.
Looking at your switch statements in both of your helper methods, if your input matches one of the when
criteria, you set a value and then immediately return. Those return
lines don't just pop you out of the switch
, it pops you out of the entire method.
Thus, if your tests are only providing input that will match one of the when
criteria (the "happy path"), you'll never reach those final return
lines in your two helper methods.
No reach = no execution = no coverage.
Honestly though, all of those return
lines inside of your when
blocks are only hurting you here. The behavior of switch
in Apex is to execute either one or zero blocks inside the switch
, and then move on to the next statement.
If you were to remove the return;
line in each of your when
blocks, you would reach the final return;
at the end of both of your helper methods and you'd get your coverage for that line.
If you do follow that advice, then you should also add some more error checking (what if month
is null? what if it's less than 1? what if it's greater than 12?) as well as test methods to stress those situations.
Looking at the other answers though, I agree that switch
isn't really the best tool for the job here.
You would need to pass in a null value to the method to reach the "default" value. Since that's not possible, you might consider optimizing your code to return a value in default, which should negate the need for a default return.
global static String getMonthName (Integer Month){
Switch on Month{
when 1 { return 'January'; }
when 2 { return 'February'; }
when 3 { return 'March'; }
when 4 { return 'April'; }
when 5 { return 'May'; }
when 6 { return 'June'; }
when 7 { return 'July'; }
when 8 { return 'August'; }
when 9 { return 'September'; }
when 10 { return 'October'; }
when 11 { return 'November'; }
when else { return 'December'; }
}
}
Switch statements can do what you're doing, but this would be just as efficient:
static String[] monthNames = new String[] { 'January','February','March','April','May','June','July','August','September','October','November','December' };
global static string getMonthName(Integer month) {
return monthNames[month-1];
}