I am trying to write junit test case using powermock for aem scheduler, its not invoking the run method. Any pointers appreciated
Solved! Go to Solution.
Views
Replies
Total Likes
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");
}
}
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 AEM: https://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
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");
}
}