I have an enum switch more or less like this:
public static enum MyEnum {A, B}
public int foo(MyEnum value) {
switch(value) {
case(A): return calculateSomething();
case(B): return calculateSomethingElse();
}
throw new IllegalArgumentException("Do not know how to handle " + value);
}
and I'd like to have all the lines covered by the tests, but as the code is expected to deal with all possibilities, I cannot supply a value without its corresponding case statement in the switch.
Extending the enum to add an extra value is not possible, and just mocking the equals method to return false
won't work either because the bytecode generated uses a jump table behind the curtains to go to the proper case... So I've thought that maybe some black magic could be achieved with PowerMock or something.
Thanks!
edit:
As I own the enumeration, I've thought that I could just add a method to the values and thus avoid the switch issue completely; but I'm leaving the question as it's still interesting.
Here is a complete example.
The code is almost like your original (just simplified better test validation):
And here is the unit test with full code coverage, the test works with Powermock (1.4.10), Mockito (1.8.5) and JUnit (4.8.2):
Result:
jMock (at least as of version 2.5.1 that I'm using) can do this out of the box. You will need to set your Mockery to use ClassImposterizer.
@Melloware
I have this same Problem. Run your test with new Enum as first in your Test Class. I created bug with this Problem: https://code.google.com/p/powermock/issues/detail?id=440
As you indicated in your edit, you can add the functionaliy in the enum itself. However, this might not be the best option, since it can violate the "One Responsibility" principle. Another way to achieve this is to create a static map which contains enum values as key and the functionality as value. This way, you can easily test if for any enum value you have a valid behavior by looping over all the values. It might be a bit far fetched on this example, but this is a technique I use often to map resource ids to enum values.
Rather than using some radical bytecode manipulation to enable a test to hit the last line in
foo
, I would remove it and rely on static code analysis instead. For example, IntelliJ IDEA has the "Enumswitch
statement that misses case" code inspection, which would produce a warning for thefoo
method if it lacked acase
.First of all Mockito can create mock data which can be integer long etc It cannot create right enum as enum has specific number of ordinal name value etc so if i have an enum
so i have total 5 ordinal in enum HttpMethod but mockito does not know it .Mockito creates mock data and its null all the time and you will end up in passing a null value . So here is proposed solution that you randomize the ordinal and get a right enum which can be passed for other test
Output :