Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mock an enum using Mockito in Java

How can I mock an enum for testing purposes using Mockito? Given this sample for the enum:

public enum TestEnum {
 YES,
 NO
}

and this one for the method using the enum:

public static boolean WorkTheEnum(TestEnum theEnum) {
switch (theEnum) {
  case YES:
     return true;
  case NO:
     return false;
  default:
     // throws an exception here
 }
}

how can I mock the enum to reach the default branch of the switch loop? This answer says Mockito can't mock enums but the answer has also been provided more than a year ago. Do I can mock an enum meanwhile or have I to let the branch stay untested? Other Mocking frameworks can't be used.

like image 941
Arthur Eirich Avatar asked Jul 06 '16 12:07

Arthur Eirich


People also ask

Can you mock an enum with Mockito?

Mockito 2 supports mocking of enum, but it is experimental feature. It needs to be enabled explicitly.

Can we mock enum in Java?

Yes! also static methods. I'll show here an enum and two different tests.

What can be mocked with Mockito?

Mockito @Mock Annotation We can mock an object using @Mock annotation too. It's useful when we want to use the mocked object at multiple places because we avoid calling mock() method multiple times. The code becomes more readable and we can specify mock object name that will be useful in case of errors.

How do you use Powermockito?

To use PowerMock with Mockito, we need to apply the following two annotations in the test: @RunWith(PowerMockRunner. class): It is the same as we have used in our previous examples. The only difference is that in the previous example we have used MockitoUnitRunner.


1 Answers

There are two answers to that:

a) you could turn to some PowerMock-like mocking framework. My two cent(entences) there: don't do that. PowerMock opens a door to the land of pain; which you do not want to enter.

b) put interfaces on your enums

Seriously; I nowadays think that there is only one good use case for enums; and that is to use them as singletons that provide a certain service. And then, I do this:

public interface FooService { void foo(); }
class FooServiceImpl implements FooService { @Override void foo() ...
enum FooServiceProvider implements FooService {
   INSTANCE;
   private final FooService impl  = new FooServiceImpl();
   @Override foo() { impl.foo()

Of course, this doesn't really help when you use enums like you do. But the thing is: you shouldn't be using enums that way anyway. Because using enums this way leads to shattered code - every place that takes an enum variable is in need for such switch statements; with all the negative consequences when you add / remove enum cases.

So, in your case: consider turning to true OO designs - where you have abstract base classes that define methods; and then you use factories to create subclasses (probably based on enum switches) that give you objects that simply do the right thing.

like image 81
GhostCat Avatar answered Oct 04 '22 22:10

GhostCat