Mocking dependencies and code coverage tool shows not executed code - java

i'm trying to test my bean as a component itself. So that the method i want to test gets executed correctly. Therefore i'm mocking it's dependencies with JMockit. I wrote two tests, one for validating the if condition to true, so the method ends immediately and returns null.The second one for executing the code below this condition also resulting in returning null. But my code coverage tool (JaCoCo) just shows that the if condition is executed and not the code below.
Session is a field in the super class ÀbstractBean. The method isLoggedIn() invokes session.isLoggedIn() and is defined in AbstractBean.
TrendBean
#Named(value = "trendBean")
#ViewScoped
#SuppressWarnings("deprecation")
public class TrendBean extends AbstractBean implements Serializable {
private static final long serialVersionUID = -310401000218411384L;
private static final Logger logger = Logger.getLogger(TrendBean.class);
private ChartPoint point;
private List<ChartPoint> points;
#Inject
private ITrendManager manager;
public String addChartPoint() {
if (!isLoggedIn()) {
return null; //only this block is executed
}
assertNotNull(point);
final User user = getSession().getUser();
manager.addPointToUser(user, point);
FacesContext.getCurrentInstance().addMessage(
null,
new FacesMessage(FacesMessage.SEVERITY_INFO,
getTranslation("pointAdded"), ""));
init();
return null;
}
}
TrendBeanTest
public class TrendBeanTest {
#Tested
TrendBean trendBean;
#Injectable
LoginBean loginBean;
#Injectable
Session session;
#Injectable
ITrendManager manager;
#Injectable
IUserManager userManager;
#Test
public void testAddChartPoint() {
new NonStrictExpectations() {
{
session.isLoggedIn();
result = true;
session.getUser();
result = (User) any;
manager.addPointToUser((User) any, (ChartPoint) any);
};
};
Deencapsulation.setField(trendBean, "point", new ChartPoint());
assertEquals(null, trendBean.addChartPoint());
}
#Test
public void testAddChartPointNotLoggedIn() {
new Expectations() {
{
manager.addPointToUser((User) any, (ChartPoint) any);
times = 0;
};
};
Session s = new Session();
s.setUser(null);
Deencapsulation.setField(trendBean, "session", s);
assertEquals(null, trendBean.addChartPoint());
}
}
AbstractBean
public abstract class AbstractBean {
private static final Logger logger = Logger.getLogger(AbstractBean.class);
#Inject
private Session session;
public boolean isLoggedIn() {
return session.isLoggedIn();
}
}

For anyone having familiar problems the statement
session.isLoggedIn();
result = true;
in Expectations Block was the answer. Although i'm facing new problems, i'm going to ask a new question.

Related

How to fully test coverage a constructor that has a System.getenv("name") operation inside

I am using JUNIT5, have been trying to fully coverage a piece of code that involves System.getenv(""); I writed a couple classes to replicate what I am experiencing right now and so you can use them to understand me also (minimal reproducible example):
First we have the service I need to get with full coverage (ServiceToTest.class) (it has a CustomContainer object which contains methods that it needs):
#Service
public class ServiceToTest {
private final CustomContainer customContainer;
public ServiceToTest() {
Object configuration = new Object();
String envWord = System.getenv("envword");
this.customContainer = new CustomContainer(configuration, envWord == null ? "default" : envWord);
}
public String getContainerName() {
return customContainer.getContainerName();
}
}
CustomContainer.class:
public class CustomContainer {
#Getter
String containerName;
Object configuration;
public CustomContainer(Object configuration, String containerName) {
this.configuration = configuration;
this.containerName = containerName;
}
}
I have tried using ReflectionTestUtils to set the envWord variable without success... I tried this https://stackoverflow.com/a/496849/12085680, also tried using #SystemStubsExtension https://stackoverflow.com/a/64892484/12085680, and finally I also tried using Spy like in this answer https://stackoverflow.com/a/31029944/12085680
But the problem is that this variable is inside the constructor so this only executes once and I think that it happens before any of this configs I tried before can apply, here is my test class:
#ExtendWith(MockitoExtension.class)
class TestService {
// I have to mock this becase in real project it has methods which I need mocked behavour
private static CustomContainer mockCustomContainer = mock(CustomContainer.class);
// The serviceToTest class in which I use ReflectionTestUtils to use the mock above
// Here is where the constructor gets called and it happens BEFORE (debuged) the setup method
// which is anotated with #BeforeAll
private static ServiceToTest serviceToTest = new ServiceToTest();
#BeforeAll
static void setup() {
// set the field customContainer at serviceToTest class to mockCustomContainer
ReflectionTestUtils.setField(serviceToTest, "customContainer", mockCustomContainer);
}
#Test
void testGetContainerNameNotNull() {
assertNull(serviceToTest.getContainerName());
}
}
I need to write a test in which serviceToTest.getContainerName is not null but the real purpose of this is to have coverage of this sentence envWord == null ? "default" : envWord so it would be a test that is capable of executing the constructor and mocking System.getenv() so that it returns not null...
Right now the coverage looks like this and I can not find a way to make it 100% Any ideas??
EDIT:
So after following tgdavies suggestion, the code can be 100% covered, so this is the way:
Interface CustomContainerFactory:
public interface CustomContainerFactory {
CustomContainer create(Object configuration, String name);
}
CustomContainerFactoryImpl:
#Service
public class CustomContainerFactoryImpl implements CustomContainerFactory {
#Override
public CustomContainer create(Object configuration, String name) {
return new CustomContainer(configuration, name);
}
}
EnvironmentAccessor Interface:
public interface EnvironmentAccessor {
String getEnv(String name);
}
EnvironmentAccessorImpl:
#Service
public class EnvironmentAccessorImpl implements EnvironmentAccessor {
#Override
public String getEnv(String name) {
return System.getenv(name);
}
}
Class ServiceToTest after refactoring:
#Service
public class ServiceToTest {
private final CustomContainer customContainer;
public ServiceToTest(EnvironmentAccessor environmentAccessor, CustomContainerFactory customContainerFactory) {
Object configuration = new Object();
String envWord = environmentAccessor.getEnv("anything");
this.customContainer = customContainerFactory.create(configuration, envWord == null ? "default" : envWord);
}
public String getContainerName() {
return customContainer.getContainerName();
}
}
Finally the test case after refactoring (here is were I think it can be improved maybe?):
#ExtendWith(MockitoExtension.class)
class TestService {
private static CustomContainer mockCustomContainer = mock(CustomContainer.class);
private static CustomContainerFactory customContainerFactoryMock = mock(CustomContainerFactoryImpl.class);
private static EnvironmentAccessor environmentAccessorMock = mock(EnvironmentAccessorImpl.class);
private static ServiceToTest serviceToTest;
#BeforeAll
static void setup() {
when(environmentAccessorMock.getEnv(anyString())).thenReturn("hi");
serviceToTest = new ServiceToTest(environmentAccessorMock, customContainerFactoryMock);
ReflectionTestUtils.setField(serviceToTest, "customContainer", mockCustomContainer);
when(serviceToTest.getContainerName()).thenReturn("hi");
}
#Test
void testGetContainerNameNotNull() {
assertNotNull(serviceToTest.getContainerName());
}
#Test
void coverNullReturnFromGetEnv() {
when(environmentAccessorMock.getEnv(anyString())).thenReturn(null);
assertAll(() -> new ServiceToTest(environmentAccessorMock, customContainerFactoryMock));
}
}
Now the coverage is 100%:
EDIT 2:
We can improve the test class and get the same 100% coverage like so:
#ExtendWith(MockitoExtension.class)
class TestService {
private static CustomContainer mockCustomContainer = mock(CustomContainer.class);
private static IContainerFactory customContainerFactoryMock = mock(ContainerFactoryImpl.class);
private static IEnvironmentAccessor environmentAccessorMock = mock(EnvironmentAccessorImpl.class);
private static ServiceToTest serviceToTest;
#BeforeAll
static void setup() {
when(environmentAccessorMock.getEnv(anyString())).thenReturn("hi");
when(customContainerFactoryMock.create(any(), anyString())).thenReturn(mockCustomContainer);
serviceToTest = new ServiceToTest(environmentAccessorMock, customContainerFactoryMock);
}
#Test
void testGetContainerNameNotNull() {
assertNotNull(serviceToTest.getContainerName());
}
#Test
void coverNullReturnFromGetEnv() {
when(environmentAccessorMock.getEnv(anyString())).thenReturn(null);
assertAll(() -> new ServiceToTest(environmentAccessorMock, customContainerFactoryMock));
}
}
Refactor your code to make it testable, by moving object creation and static method calls to components, which you can mock in your tests:
interface ContainerFactory {
CustomContainer create(Object configuration, String name);
}
interface EnvironmentAccessor {
String getEnv(String name);
}
#Service
public class ServiceToTest {
private final CustomContainer customContainer;
public ServiceToTest(ContainerFactory containerFactory, EnvironmentAccessor environmentAccessor) {
Object configuration = new Object();
String envWord = environmentAccessor.getEnv("envword");
this.customContainer = containerFactory.create(configuration, envWord == null ? "default" : envWord);
}
public String getContainerName() {
return customContainer.getContainerName();
}
}

How do I write JUnit test to cover both branches of an if statement

New in JUnit here. I am using JUnit 4 with Mockito. How do I write junit for "if" condition?
Note: I am trying to cover inside the if statement when question is not null. Hopefully my question makes sense.
public class MyClass{
private HttpServletRequest request;
private A a;
private B b;
public void go(String something, String s){
MyQuestion question = Exam.getSubject().getMarks(a.getAId, b.getBId(), something);
if(question !=null){
request.setAttribute(s, question);
}
}
}
// getMarks I do have catching an exception
Here is the snippet:
public class MarksClass{
Public MyQuestion getMarks(long idA, long IdB, String s){
try{
//some code
}catch(Exception e){
throw new SomeException("exception" + e);
}
}
}
Assuming, "getSubject" returns a field with name "subject".
final HttpServletRequest mockedRequest = Mockito.mock(HttpServletRequest.class);
ReflectionTestUtils.setField(myClass, "request", mockedRequest);
final MarksClass mockedMarksClass = Mockito.mock(MarksClass.class);
final MyQuestion mockedResult = Mockito.mock(MyQuestion.class);
Mockito.when(mockedMarksClass.getMarks(Mockito.anyLong(), Mockito.anyLong(), Mockito.anyString()).thenReturn(mockedResult);
ReflectionTestUtils.setField(myClass, "subject", mockedMarksClass);
//... rest of the test
Design your class in such a way that testing becomes easy. Or change the design so that it can be tested more easily.
Having global singletons makes testing difficult, if not impossible. The general way forward is to have a class injected with all its external dependencies (DI, dependency injection) or pass the dependencies as arguments to the method.
public class MyClass {
private HttpServletRequest request;
private A a;
private B b;
private final Supplier<Subject> subjectFactory;
public MyClass(final Supplier<Subject> subjectFactory) {
this.subjectFactory = subjectFactory;
}
public void go(String something, String s){
final MyQuestion question = subjectFactory.get().getMarks(a.getAId, b.getBId(), something);
if(question !=null){
request.setAttribute(s, question);
}
}
}
Then in your real code, initialize the class with a method reference to the method on your singleton:
final MyClass myClass = new MyClass(Exam::getSubject);
And in your test inject a test double:
new MyClass(() -> new Subject() {
#Override
public MyQuestion getMarks(…) {
return null;
}
);
Of course, nothing is prevent you from changing the Supplier<Subject> to a Supplier<MyQuestion>, Function<String, MyQuestion>, or a custom interface; and then replacing this with a test double.
#FunctionalInterface
public interface Grader {
MyQuestion getMarks(String idA, String idB, String something);
}
public class MyClass {
private HttpServletRequest request;
private A a;
private B b;
private final Grader grader;
public MyClass(final Grader grader) {
this.grader = grader;
}
public void go(String something, String s){
final MyQuestion question = grader.getMarks(a.getAId, b.getBId(), something);
if(question !=null){
request.setAttribute(s, question);
}
}
}
And then again in your production code vs your test code:
final MyClass production = new MyClass(Exam.getSubject()::getMarks);
final MyClass underTest = new MyClass((a, b, something) -> null);
Providing different implementations of this interface can make your code a bit more expressive:
public class ExamSubjectGrader implements Grader {
#Override
public MyQuestion getMarks(String idA, String idB, String something) {
return Exam.getSubject().getMarks(idA, idB, something);
}
}
public class NullGrader implements Grader {
#Override
public MyQuestion getMarks(String idA, String idB, String something) {
return null;
}
}
MyClass production = new MyClass(new ExamSubjectGrader());
MyClass underTest = new MyClass(new NullGrader());
(both of those are actually singletons, but they could have their own dependencies or state).
And as you can see: you don't even need a heavy mocking library such as Mockito. Good ol' Java can do that just fine.
Find more details in the question Why is my class not using my mock in unit test?

Why is #AfterReturning is never called

I have this method and it does return a list:
public List<ReportReconciliationEntry> getMissingReports(List<ReportReconciliationEntry> expectedReports,
List<GeneratedReportContent> generatedReports){
...
return missingReports;
}
but this method is never called:
#AfterReturning(value = "execution(* com.XXX.YYY.ZZZ.service.ReconciliationService.getMissingReports(..)) && args(expectedReports,generatedReports)", argNames = "expectedReports,generatedReports,missingReports", returning = "missingReports")
public void logReportReconciliationException(List<ReportReconciliationEntry> expectedReports, List<GeneratedReportContent> generatedReports, List<ReportReconciliationEntry> missingReports) {
final String notApplicable = properties.getNotApplicable();
ReportingAlertMarker marker = ReportingAlertMarker.builder()
.eventType(E90217)
.userIdentity(notApplicable)
.destinationIp(properties.getDestinationIp())
.destinationPort(properties.getDestinationPort())
.dataIdentity(notApplicable)
.resourceIdentity(notApplicable)
.responseCode(404)
.build();
MDC.put(SYSTEM_COMPONENT, properties.getBpsReportGenerationService());
System.out.println(missingReports);
logWrapper.logError(marker, "SDGFHDZFHDFR!!");
}
I check the return of the first method with a breakpoint. It does return a list, but the #AfterReturning is never called, although the IDE shows the "Navigate to AOP advices" icon. What am I missing?
This is what my class looks like:
#Component
#Aspect
#Slf4j
public class ReportingAlertAspect {
private final LogWrapper logWrapper;
private final ReportingAlertProperties properties;
public ReportingAlertAspect(final ReportingAlertProperties properties, final LogWrapper logWrapper) {
this.logWrapper = logWrapper;
this.properties = properties;
}
....
}
I have another class with a function in it and this one works fine:
#Component
#Aspect
#Slf4j
public class ReportingInfoAspect {
private final LogWrapper logWrapper;
private final ReportingAlertProperties properties;
#AfterReturning(value = "execution(* com.xxx.yyy.zzz.qqq.ReconciliationService.reconcile(..)) && args(windowId)", argNames = "windowId,check",
returning = "check")
public void logSuccessfulReportReconciliation(ReconciliationEvent windowId, boolean check){
String notApplicable = properties.getNotApplicable();
MDC.put(SYSTEM_COMPONENT, properties.getBpsReportGenerationService());
ReportingAlertMarker marker = ReportingAlertMarker.builder()
.eventType(E90293)
.userIdentity(notApplicable)
.destinationIp(properties.getDestinationIp())
.destinationPort(properties.getDestinationPort())
.dataIdentity(notApplicable)
.resourceIdentity(notApplicable)
.responseCode(200)
.build();
if (check){
logWrapper.logInfo(marker, "All reports for windowId {} were generated successfully", windowId.windowId);
}
}
}
I found the problem.
The getMissingReports method was called from another method inside the same class. This is a case of self-invocation and the method was never called through the proxy.
This is what the class looks like:
#Service
#RequiredArgsConstructor
public class ReconciliationService {
private final ReconciliationRepository reconciliationRepository;
private final ReportSafeStoreClientService reportSafeStoreClientService;
#Handler
public whatever whatever() {
...
getMissingReports()
}
}
You can find more info here

Unit test singleton class method in android using PowerMock

I need to do unit testing of methods of Singleton class which internally uses RxJava Singles, and used PowerMock test framework to mock static class and methods. I tried various method to mock Schedulers.io() and AndroidSchedulers.mainThread() methods but it's not working. I'm getting java.lang.NullPointerException error at line .subscribeOn(Schedulers.io()) inside UserApi.verifyUserData() method.
Singleton Class UserApi (Class under Test)
final public class UserApi {
private CompositeDisposable compositeDisposable;
private String userID;
//private final SchedulerProvider schedulerProvider;
private UserApi(String userId) {
super();
this.userID = userId;
//this.schedulerProvider = schedulerProvider;
}
public static UserApi getInstance() {
return SingletonHolder.sINSTANCE;
}
private static final class SingletonHolder {
private static final UserApi sINSTANCE;
static {
String uuid = UUID.randomUUID().toString();
sINSTANCE = new UserApi(uuid);
}
}
// Rest Api call
public void verifyUserData(byte[] doc, byte[] img) {
this.compositeDisposable = new CompositeDisposable();
String docStr = Base64.encodeToString(doc, Base64.NO_WRAP);
String imgStr = Base64.encodeToString(img, Base64.NO_WRAP);
final Disposable apiDisposable = IdvManager.getInstance().getUserManager().verifyUserData(docStr, imgStr)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<JsonObject>() {
#Override
public void accept(JsonObject verifyResponse) throws Exception {
pollResult();
}
}, new Consumer<Throwable>() {
#Override
public void accept(Throwable error) throws Exception {
// handle error code...
}
});
this.compositeDisposable.add(apiDisposable);
}
private void pollResult() {
// code here...
}
}
UserManager Class and Interface
public interface UserManager {
Single<JsonObject> verifyUserData(String docStr, String imgStr);
}
final class UserManagerImpl implements UserManager {
private final UserService userService;
UserManagerImpl(final Retrofit retrofit) {
super();
this.userService = retrofit.create(UserService.class);
}
#Override
public Single<JsonObject> verifyUserData(String docStr, String imgStr) {
// Code here...
}
}
Unit Test
#RunWith(PowerMockRunner.class)
#PrepareForTest({IdvManager.class, Base64.class, Schedulers.class, AndroidSchedulers.class, UserApi.class})
public class UserApiTest {
#Mock
public UserManager userManager;
#Mock
private Handler handler;
private IdvManager idvManager;
private Schedulers schedulers;
private UserApi spyUserApi;
private TestScheduler testScheduler;
private String userID;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
testScheduler = new TestScheduler();
handler = new Handler();
PowerMockito.suppress(constructor(IdvManager.class));
// mock static
PowerMockito.mockStatic(IdvManager.class);
PowerMockito.mockStatic(Schedulers.class);
PowerMockito.mockStatic(AndroidSchedulers.class);
PowerMockito.mockStatic(Base64.class);
// Create mock for class
idvManager = PowerMockito.mock(IdvManager.class);
schedulers = PowerMockito.mock(Schedulers.class);
PowerMockito.when(IdvManager.getInstance()).thenReturn(IdvManager);
when(idvManager.getUserManager()).thenReturn(userManager);
spyUserApi = PowerMockito.spy(UserApi.getInstance());
// TestSchedulerProvider testSchedulerProvider = new TestSchedulerProvider(testScheduler);
when(Base64.encodeToString((byte[]) any(), anyInt())).thenAnswer(new Answer<Object>() {
#Override
public Object answer(InvocationOnMock invocation) throws Throwable {
return java.util.Base64.getEncoder().encodeToString((byte[]) invocation.getArguments()[0]);
}
});
when(schedulers.io()).thenReturn(testScheduler);
when(AndroidSchedulers.mainThread()).thenReturn(testScheduler);
userID = UUID.randomUUID().toString();
}
#After
public void clearMocks() {
//Mockito.framework().clearInlineMocks();
}
#Test
public void verifyUserData_callsPollResult_returnsResponse() {
// Input
String docStr = "iVBORw0KGgoAAAANSUhEUgAAAJ4AAACeCAYAAADDhbN7AA.....";
// Output
JsonObject verifyResponse = new JsonObject();
verifyResponse.addProperty("status", "Response created");
doReturn(Single.just(verifyResponse)).when(userManager).verifyUserData(docStr, docStr);
// spy method call
spyUserApi.verifyUserData(docFrontArr, docFrontArr);
testScheduler.triggerActions();
// assert
verify(userManager).verifyUserData(docStr, docStr);
}
}
Error
java.lang.NullPointerException
at com.rahul.manager.UserApi.verifyUserData(UserApi.java:60)
at com.rahul.manager.UserApiTest.verifyUserData_callsPollResult_returnsResponse(UserApiTest.java:171)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
I'm not sure whether i can test methods of Singleton class by spying on real instance of Singleton class using PowerMock.
Testing your code is complex because it's not testable and it's not extensible. It contains hardcoded dependencies everywhere (e.g. user id, handler, several singletons).
If you decide to use another id generation approach or another handler, you won't be able to do this without rewriting whole class.
Instead of hardcoding dependencies, ask for them in constructor (for mandatory dependencies) or setters (for optional ones).
This will make your code extensible and testable. After you do this, you will see your class contains several responsibilities, after moving them into separate classes, you will get much better picture :-)
For example:
public UserApi(String userId, Handler handle) {
this.userId = userId;
this.handler = handler;
}
Schedulers.io() is a static method, so you need to use mockStatic (which you did) and define the related mock accordingly.
I rearranged your setup method a bit, to improve the readability and fixed the mistake. You do not need an instance of Schedulers (The variable you named schedulers).
Probably a simple typo you made, as you did the right thing for Base64 and AndroidSchedulers.
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
testScheduler = new TestScheduler();
handler = new Handler();
// mock for instance of `IdvManager`
PowerMockito.suppress(constructor(IdvManager.class));
idvManager = PowerMockito.mock(IdvManager.class);
when(idvManager.getUserManager()).thenReturn(userManager);
// mock for `IdvManager` class
PowerMockito.mockStatic(IdvManager.class);
PowerMockito.when(IdvManager.getInstance()).thenReturn(idvManager);
// mock for `Schedulers` class
PowerMockito.mockStatic(Schedulers.class);
when(Schedulers.io()).thenReturn(testScheduler);
// spy for instance of `UserApi`
spyUserApi = PowerMockito.spy(UserApi.getInstance());
// mock for `Base64` class
PowerMockito.mockStatic(Base64.class);
when(Base64.encodeToString((byte[]) any(), anyInt())).thenAnswer(new Answer<Object>() {
#Override
public Object answer(InvocationOnMock invocation) throws Throwable {
return java.util.Base64.getEncoder().encodeToString((byte[]) invocation.getArguments()[0]);
}
});
// mock for `AndroidSchedulers` class
PowerMockito.mockStatic(AndroidSchedulers.class);
when(AndroidSchedulers.mainThread()).thenReturn(testScheduler);
userID = UUID.randomUUID().toString();
}
However the NPE is missing the part that actually indicates its failing from this, consider adding it if that does not solve your problem.

Static Field as Null when mocking Enums with PowerMock

I have written a Thread Pool and I am not able to write the Junits(PowerMock) for that class.
public enum ThreadPool {
INSTANCE;
private static final String THREAD_POOL_SIZE = "threadpool.objectlevel.size";
private static TPropertyReader PROP_READER = new PropertyReader();
private final ExecutorService executorService;
private static final ILogger LOGGER = LoggerFactory
.getLogger(ReportExecutorObjectLevelThreadPool.class.getName());
ThreadPool() {
loadProperties();
int no_of_threads = getThreadPoolSize();
executorService = Executors.newFixedThreadPool(no_of_threads);
}
public void submitTask(Runnable task) {
executorService.execute(task);
}
private static void loadProperties() {
try {
PROP_READER.loadProperties("Dummy");
} catch (final OODSystemException e) {
LOGGER.severe("Loading properties for app failed!");
}
}
private int getThreadPoolSize() {
return Integer.valueOf(PROP_READER
.getProperty(THREAD_POOL_SIZE));
}
}
While Mocking this class I am getting NullPointerException in the line PROP_READER.loadProperties("DUMMY");
My Test Case is:-
PowerMockito.whenNew(PropertyReader.class).withNoArguments().thenReturn(mockPropertyReader);
PowerMockito.doNothing().when( mockPropertyReader,"loadProperties",anyString());
mockStatic(ThreadPool.class);
First you need to set your internal state of your enum as enum is final class
and the instance of an enum will be load on class loading
ThreadPool mockInstance = mock(ThreadPool .class);
Whitebox.setInternalState(ThreadPool.class, "INSTANCE", mockInstance);
then
PowerMockito.mockStatic(ThreadPool .class);
and then mocking
doNothing().when(mockInstance).loadProperties(any(String.class));
do not forget adding the following annotation to the test
#RunWith(PowerMockRunner.class)
#PrepareForTest({ThreadPool.class})
if it still not working you need to see which more member of the class you need to set in the internal state

Categories