Condition coverage on switch statement - java

When I run coverage on my code below:
private static String mapMyVal(String val) {
switch (val) {
case "foo":
return "FOO_FOO";
case "bar":
return "BARR";
default:
throw new InvalidArgumentException();
}
}
I see "8 out of 10 conditions covered" when I run my unit tests on this with coverage. However I see all three lines being covered inside the statement.
Since there are no other conditions than "foo", "bar" and everything else, what are those missing two conditions?

I see one possible case not covered. The input val might be null. In that case, your switch statement would throw a NullPointerException. To remedy this, you could add null check to the start of the method.
private static String mapMyVal(String val) {
switch (val) {
case "foo":
return "FOO_FOO";
case "bar":
return "BARR";
default:
throw new InvalidArgumentException();
}
}

There was already someone asking nearly the same question. Overall it turned out that going for 100% of unittest for a switch-case might be pure luck because of the way that java is handling the switch-case. See here eclemma branch coverage for switch: 7 of 19 missed

Related

How to Call Multiple Methods in a Switch Case in Java

I'm learning how to build a table in Java with MVC and I am trying to have a switch case that both performs changes to the data in the model and also calls a method like this
public void update()
{ model.fireTableDataChanged(); }
to update the data presented on the table.
Here is the switch case
public Object getValueAt(int row, int col)
{ switch(col)
{ case 0: return row;
case 1: return car.on(car.stops());
default: return ""; }
}
Any assistance is greatly appreciated and if you need to see more of the code to help you answer my question I will provide it.
You seem to be under the incorrect understanding that cases end at the first semicolon. This is incorrect. Cases don't end until you end them with the close brace for the overall switch statement, or until you include a break. Between the case and the end of the case, you can have any number of lines of code that do (pretty much) anything you want.
Think of a switch almost like a function, where the only* way to exit the function is to reach a break statement, return statement, or the close brace at the end, in exactly the same way that you exit functions with return and reaching the end of the function.
switch(condition) {
case 1: fcnOne();
case 2: fcnTwoA(); fcnTwoB();
case 3: fcnThree; break;
default: fcnFour();
}
If the condition is 1 then fcnOne() is called. There is no break in fcnOne(), so the code continues on into case 2. This is often called falling through. fcnTwoA() is then called. The code continues to the next instruction, which is to call fcnTwoB(). The next instruction is fcnThree(). Finally, we encounter a break statement, which exits the switch block.
Yes, I am intentionally ignoring exceptions, System.exit(), and return values for non-void functions.
I've formatted your code differently. Hopefully, it makes it easier to understand the multiple statements. Try something like this:
public Object getValueAt(int row, int col) {
switch(col) {
case 0:
// You can add any number of statements here.
...
update();
return row;
case 1:
...
update();
return car.on(car.stops());
default:
...
update();
return "";
}
}

switch inside while loop - missing return statement

There are many similar topics, but I can't find exactly where my problem is..
CustomerDetails - abstract class
The method reads from a file, where first letter determines the types of a customer (which are sub-classes of CustomerDetails).
public static CustomerDetails readCustomerData(....)
try
{
while(...hasNextLine())
{
.....
.....
switch(firstLetter)
{
case 'A': ....
PrivateCustomerDetails aaa = new PrivateCustomerDetails(... inherited fields + some extra ones)
return aaa;
case 'B': ... BusinessCustomerDetails bbb = .....
return bbb;
default: return null;
}
}
// possibly return something here..
}
catch(Exception e)
{
...
return null;
}
I have noticed that if I enter "return null;" at a comment field above, missing return statement disappear. But I cant get why? I have possible scenarios as well as default statement, which covers all other cases.
Moreover, I can't initialize CustomerDetails object, assign new objects of sub-classes to it and return, since it is abstract..
Also, I can't make the names of the objects of sub-classes the same to return it in the end..
Need some clarification.. Thanks very much!
What if hasNextLine() returns false the very first time you call it? What would be returned in that case? You need a return statement to handle that possibility.
If you don't expect that to happen, an alternative is to throw an exception.
Because it is possible that the while loop is never executed. In this case you have to return a value.

Java/C++: possible to have common code for multiple cases in switch?

I find myself running into this situation a lot and was wondering if there are way in Java or C++ or any other language for that matter that allows you to execute code that is common to multiple case statements in a switch but also specialize for individual cases aswell, e.g:
switch(var)
{
case Preceeding:
{
// code executed for both FollowingA and FollowingB
}
break;
case FollowingA:
{
// code executed for only FollowingA
}
break;
case FollowingB:
{
// code executed for only FollowingB
}
break;
}
instead of having to do this:
switch(var)
{
case FollowingA:
case FollowingB:
{
// code executed for FollowingA and FollowingB
switch(var)
{
case FollowingA:
{
// code executed for FollowingA
}
break;
case FollowingB:
{
// code executed for FollowingB
}
break;
}
}
break;
}
It really depends on what you are trying to do - not just from a "can you do this" perspective, but you also have to care for the fact that you or others will have to read and understand the code later.
I typically find that if there are some things that need to be done in more than one case of a switch, it should go into a function (most compilers will inline such code if it's small enough, so there is no performance loss).
So:
void CommonCode()
{
...
}
switch(var)
{
case A:
CommonCode();
...
break;
case B:
CommonCode();
...
break;
}
There are however quite a lot of different solutions to this problem, and it really should follow "what is the meaning of what your code does" that should guide how you solve this. Write code that is clear is the primary goal. If that doesn't work, design the code differently.
}

Java Switch use variable in multiple cases best practice

I want to have a switch statement like the following:
switch (something)
{
case 1:
int a = 3;
...
break;
case 2:
int a = 4;
....
break;
}
This does not work because a can not be redefined in that scope. I see the following options:
just go with "a = 4" in case 2
put each case in braces
define the variable before the switch statement
use a different variable name in case 2
I don't really like any of those four. Which of those is the way to go, or am i missing the best solution?
I saw questions like this one, which suggest using braces, but they are not about the best way to do it, but about getting it to work at all.
I am guessing you are catching any exception with an illegalstateexception and using a default block.
default:
doSomething();
break;
The oracle style guide does not use braces. It also says that a falls through comment should be added wherever a statement has no break.
However, anything with more than one line can be wrapped in braces with no performance penalty, for readability and reliability. The braces tell the compiler to create a new scope and execute that code as a block. If all you do is change a, then it is not really necessary. If you can write your switch case statement on one line without braces, do it. Many things in java don't do braces in one line instances including if statements.
Next, you can redefine any variable you need to re-use or set in the statements outside of the switch statement. This would be the best practice to minimize continual instantiation of your integers.
If there is more then one line,you should try making a few methods then, go with:
int a=0;
switch (something)
{
case 1:{
a = 3;
...
break;
}
case 2:{
a = 4;
....
break;
}
default:
{
try{
throw new IllegalStateException();
}catch(IllegalStateException e)
{
e.printStackTrace();
}
}
}
The braces is the right way to do it. {} creates a new scope, which is exactly what you want.
You can also use Map:
Map<Integer, Integer> caseMap = new HashMap<Integer, Integer>() {{
put(1, 3);
put(2, 4);
}};
int a = caseMap.get(something);

Weird compilation error when using switch on enumeration

I just noticed one curious case and wanted to see if someone will be able to explain it. Here is my case:
private enum Classifiers {
NEURAL_NETWORK, NEAREST_NEIGHBOURS, IDENTITY;
}
private ClassifierInterface getClassifierInstance(Classifiers classifier) {
switch (classifier) {
case NEURAL_NETWORK:
return new DoubleLayeredNeuralNetwork();
case NEAREST_NEIGHBOURS:
return new NearestNeighbours();
case IDENTITY:
return new IdentityClassifier();
}
return null; // If I comment out this line I get compilation error
}
See the comment. I would expect that Unreachable code error will be reported for this line. Instead I get Method must return value error if I comment out this line. However, there is no way the program flow will pass through there.
I even assumed it would be a guard case for the case of null value passed-in, but as expected this triggers NullPointerException for the switch condition.
I do not use switch very often, probably I am missing something here. Can somebody please try to help understand this behaviour?
That is correct behaviour as you do not have a default case statement. The problem is that you could add an value to the enum later and not re-compile the code which uses it. By forcing you to always handle when it is not one of the values, this is covered.
BTW: classifier could be null which is another option switch doesn't handle unfortunately.
That question is interesting...
We have something like this and the compiler is happy!
public enum Coin {
PENNY,
NICKEL,
DIME,
QUARTER;
}
private enum CoinColor { COPPER, NICKEL, SILVER }
private static CoinColor color(Coin c) {
switch(c) {
case PENNY:
return CoinColor.COPPER;
case NICKEL:
return CoinColor.NICKEL;
case DIME: case QUARTER:
return CoinColor.SILVER;
default:
throw new AssertionError("Unknown coin: " + c);
}
}
The Java Languaje Specification says:
A Java compiler is encouraged (but not required) to provide a warning
if a switch on an enum-valued expression lacks a default label and
lacks case labels for one or more of the enum type's constants. (Such
a statement will silently do nothing if the expression evaluates to
one of the missing constants.)

Categories