Expand my Community achievements bar.

SOLVED

I am trying to write junit test case using powermock for aem scheduler, its not invoking the run method. Any pointers appreciated

Avatar

Level 4

I am trying to write junit test case using powermock for aem scheduler, its not invoking the run method. Any pointers appreciated

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

Hi @manisha594391 ,
Sharing code snipped. Try to use Junit5 and aem specific frameworks to write unit tests. 

try to use AemContextExtension and MockitoExtension if needed

@ExtendWith({AemContextExtension.class, MockitoExtension.class})

Sharing code snippet for schedulerTest for run method.  Please check complete working demo files in git.

Scheduler

@Component(immediate = true, service = Runnable.class)
@Designate(ocd = SchedulerConfiguration.class)
public class GeeksScheduler implements Runnable {
private static final Logger LOG = LoggerFactory.getLogger(GeeksScheduler.class);

private int schedulerId;

@Reference
private Scheduler scheduler;

@Activate
protected void activate(SchedulerConfiguration config) {
schedulerId = config.schedulerName().hashCode();
addScheduler(config);
}

@Deactivate
protected void deactivate(SchedulerConfiguration config) {
removeScheduler();
}

protected void removeScheduler() {
scheduler.unschedule(String.valueOf(schedulerId));
}

protected void addScheduler(SchedulerConfiguration config) {
ScheduleOptions scheduleOptions = scheduler.EXPR(config.cronExpression());
scheduleOptions.name(String.valueOf(schedulerId));
scheduler.schedule(this, scheduleOptions);
}
@Override
public void run() {
LOG.info("\n ====> RUN METHOD");
}
}

Test Class

@ExtendWith(AemContextExtension.class)
class GeeksSchedulerTest {

AemContext aemContext=new AemContext();
private TestLogger LOG ;
private GeeksScheduler schedulerTest;
SchedulerConfiguration schedulerConfiguration;
int schedulerId;

@BeforeEach
void setUp() {
schedulerTest=aemContext.registerService(new GeeksScheduler());
LOG=TestLoggerFactory.getTestLogger(schedulerTest.getClass());
schedulerConfiguration=mock(SchedulerConfiguration.class);
when(schedulerConfiguration.schedulerName()).thenReturn("Geeks Scheduler");
when(schedulerConfiguration.cronExpression()).thenReturn("0/20 * * * * ?");

}

@Test
void run() {
schedulerTest.run();
List<LoggingEvent> logEvents = LOG.getLoggingEvents();
assertEquals(1,logEvents.size());
assertEquals(Level.INFO,logEvents.get(0).getLevel());
assertEquals("\n ====> RUN METHOD",logEvents.get(0).getMessage());
assertEquals(schedulerConfiguration.schedulerName(),"Geeks Scheduler");
}

}

 

https://github.com/aemgeeks1212/aemgeeks/blob/master/core/src/test/java/com/aem/geeks/core/scheduler...

https://github.com/aemgeeks1212/aemgeeks/blob/master/core/src/main/java/com/aem/geeks/core/scheduler...

https://github.com/aemgeeks1212/aemgeeks/blob/master/core/src/main/java/com/aem/geeks/core/config/Sc...

 

 

View solution in original post

2 Replies

Avatar

Community Advisor

Hi @manisha594391 

AEM provides options for mocking or simulating AEM resources when writing unit tests. Recommendation to follow AEM best Practices and use 

The JUnit5, Mockito and AEM Mocks test dependencies are automatically added to the project during setup using the AEM Maven archetype.

AEM test context using wcm.io’s AemContext

Most code written for AEM relies on JCR, Sling or AEM APIs, which in turn, require the context of a running AEM to execute properly, thus wcm.io’s AEM Mocks creates mock context that allows these APIs to mostly act as if they are running in AEM.


For more details please visit this article: https://experienceleague.adobe.com/docs/experience-manager-learn/getting-started-wknd-tutorial-devel...


Furthermore, still few clients wants to use PowerMockito Frameworks for some reason, hence sharing sample code snippet here to understand PowerMockito extension
Junit tests using Mockito & PowerMockito with AEMhttps://www.bhasaka.com/junit-tests-using-mockito-powermockito/


FileImporterService.java

package com.demo.csvservices;

import org.apache.felix.scr.annotations.*;

@Component(label = "Demo fileImporter", immediate = true, policy = ConfigurationPolicy.REQUIRE)
@Service
@Property(name = Importer.SCHEME_PROPERTY, value = "fileImporter")
public class FileImporterService implements Runnable {

@Override
public void run() {
log.info("Running...");
}
}

FileImporterServiceTest.java

package com.demo.csvservices;

import org.apache.sling.api.resource.Resource;
import org.apache.sling.commons.osgi.PropertiesUtil;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@RunWith(PowerMockRunner.class)
@PrepareForTest({FileImporterService.class})
public class FileImporterServiceTest {

@Mock
CSVService csvService;

@Mock
Resource resource;

@Before
public void setUp() {
PowerMockito.doNothing().when(csvService).parsingCSVFiles(anyString(), any(Resource.class));
when(resource.getPath()).thenReturn("/abc");
}

@Test
public void test_run() {
fileImporterService.run();
}
}

 Hope this helps you for setting up classes, mocking variables etc.

Regards,
Santosh

Avatar

Correct answer by
Community Advisor

Hi @manisha594391 ,
Sharing code snipped. Try to use Junit5 and aem specific frameworks to write unit tests. 

try to use AemContextExtension and MockitoExtension if needed

@ExtendWith({AemContextExtension.class, MockitoExtension.class})

Sharing code snippet for schedulerTest for run method.  Please check complete working demo files in git.

Scheduler

@Component(immediate = true, service = Runnable.class)
@Designate(ocd = SchedulerConfiguration.class)
public class GeeksScheduler implements Runnable {
private static final Logger LOG = LoggerFactory.getLogger(GeeksScheduler.class);

private int schedulerId;

@Reference
private Scheduler scheduler;

@Activate
protected void activate(SchedulerConfiguration config) {
schedulerId = config.schedulerName().hashCode();
addScheduler(config);
}

@Deactivate
protected void deactivate(SchedulerConfiguration config) {
removeScheduler();
}

protected void removeScheduler() {
scheduler.unschedule(String.valueOf(schedulerId));
}

protected void addScheduler(SchedulerConfiguration config) {
ScheduleOptions scheduleOptions = scheduler.EXPR(config.cronExpression());
scheduleOptions.name(String.valueOf(schedulerId));
scheduler.schedule(this, scheduleOptions);
}
@Override
public void run() {
LOG.info("\n ====> RUN METHOD");
}
}

Test Class

@ExtendWith(AemContextExtension.class)
class GeeksSchedulerTest {

AemContext aemContext=new AemContext();
private TestLogger LOG ;
private GeeksScheduler schedulerTest;
SchedulerConfiguration schedulerConfiguration;
int schedulerId;

@BeforeEach
void setUp() {
schedulerTest=aemContext.registerService(new GeeksScheduler());
LOG=TestLoggerFactory.getTestLogger(schedulerTest.getClass());
schedulerConfiguration=mock(SchedulerConfiguration.class);
when(schedulerConfiguration.schedulerName()).thenReturn("Geeks Scheduler");
when(schedulerConfiguration.cronExpression()).thenReturn("0/20 * * * * ?");

}

@Test
void run() {
schedulerTest.run();
List<LoggingEvent> logEvents = LOG.getLoggingEvents();
assertEquals(1,logEvents.size());
assertEquals(Level.INFO,logEvents.get(0).getLevel());
assertEquals("\n ====> RUN METHOD",logEvents.get(0).getMessage());
assertEquals(schedulerConfiguration.schedulerName(),"Geeks Scheduler");
}

}

 

https://github.com/aemgeeks1212/aemgeeks/blob/master/core/src/test/java/com/aem/geeks/core/scheduler...

https://github.com/aemgeeks1212/aemgeeks/blob/master/core/src/main/java/com/aem/geeks/core/scheduler...

https://github.com/aemgeeks1212/aemgeeks/blob/master/core/src/main/java/com/aem/geeks/core/config/Sc...