Hello Everyone,
I need to write the junit for Event Listener. Attaching the sample code for reference. Could you please suggest the best way of writing the junit for Event Listener.
package myproject.core.listeners;
import java.util.HashMap;
import java.util.Map;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.observation.Event;
import javax.jcr.observation.EventListener;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.day.cq.commons.Externalizer;
import myproject.core.service.EmailService;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.osgi.service.component.ComponentContext;
import javax.jcr.observation.EventIterator;
@component(immediate = true, service = EventListener.class)
public class UserNotificationListener implements EventListener {
Logger log = LoggerFactory.getLogger(this.getClass());
private Session adminSession;
String nodePath = StringUtils.EMPTY;
@reference
org.apache.sling.jcr.api.SlingRepository repository;
@reference
private ResourceResolverFactory resourceResolverFactory;
@reference
Externalizer externalizer;
@reference
private transient EmailService emailService;
@activate
public void activate(ComponentContext context) throws Exception {
log.info("activating ExampleObservation");
try {
adminSession = repository.loginService("datawrite", null);
adminSession.getWorkspace().getObservationManager().addEventListener(
this, //handler
Event.PROPERTY_ADDED | Event.NODE_ADDED, //binary combination of event types
"/home/users", //path
true, //is Deep?
null, //uuids filter
null, //nodetypes filter
false);
} catch(RepositoryException e) {
log.error("unable to register session", e);
throw new Exception(e);
}
}@Deactivate
public void deactivate() {
if (adminSession != null) {
adminSession.logout();
}
}
public void onEvent(EventIterator eventIterator) {
try {
while (eventIterator.hasNext()) {
Event event = eventIterator.nextEvent();
nodePath = event.getPath();
if (nodePath != null && nodePath.contains("email")) {
Node root = adminSession.getRootNode();
String profilepath = nodePath.substring(1, nodePath.lastIndexOf("/"));
log.info("profilepath path : {}", profilepath);
String externalurlprefix = profilepath.substring(0, profilepath.lastIndexOf("/"));
Node user_node = root.getNode(externalurlprefix);
String userName =user_node.getProperty("rep:principalName").getString();
// log.info("user_node userName" + user_node.getProperty("rep:principalName").getString());
// log.info("user_node password" + user_node.getProperty("rep:password").getString());
Node another_node = root.getNode(profilepath);
String emailAddress =another_node.getProperty("email").getString();
log.info("EmailId Node" + another_node.getProperty("email").getString());
ResourceResolver resourceResolver = null;
Map < String,Object > paramMap = new HashMap < String,Object > ();
// paramMap.put(ResourceResolverFactory.SUBSERVICE, "socialService");
paramMap.put(ResourceResolverFactory.SUBSERVICE, "datawrite");
resourceResolver = resourceResolverFactory.getServiceResourceResolver(paramMap);
String myExternalizedUrl = externalizer.authorLink(resourceResolver, "/libs/granite/security/content/v2/usereditor") + ".html/" + externalurlprefix;
Map < String,
String > emailParams = new HashMap < String,
String > ();
emailParams.put("userName", userName);
emailParams.put("recipient", emailAddress);
emailParams.put("emailSubject", "You’ve been invited to join the Intuit Asset Library.");
emailParams.put("message", "You’ve been invited to join the asset library.");
emailParams.put("passwordLinksHTML", myExternalizedUrl);
String recipientEmail = emailService.sendMail(resourceResolver, emailParams, emailAddress);
if (StringUtils.isEmpty(recipientEmail)) {
log.info("mail not sent");
} else {
log.info("mail sent successfully");
}
}
}
} catch(Exception e) {
log.error("Error while treating events", e);
}
}
}
Solved! Go to Solution.
Views
Replies
Total Likes
The cleanest way to unit test this is to simply test is an OSGi service using AEM Mocks [1] (which are a super-set of Sling Mocks/JCR mocks [2]).
You can see how something (of similar complexity, though a servlet) is achieved via this unit test [3]
Basically you'll need to:
1. Create a Unit Test using Mockito and AEM Mocks
2. In the @Before method
2. In your test case, injectAndActivate an instance of your EventListener along w/ any OSGi config properties you want to test it with)
3. Then, using the OSGi mock context get that service back using the interface (you can optionally cast the service to your impl class if you want to discretely test methods that arent on the interface).
4. Then you can test the service.
Note that as mentioned on [2] - with JcrMocks "Observation events can be registered but are ignored" - so looks like you'll mock that context when you test onEvent(..).
FWIW I think you'll end up spending some time getting it all mocked up/tested -- you may find that you want to refactor your code to be more testable as well.
[1] https://wcm.io/testing/aem-mock/
[2] https://sling.apache.org/documentation/development/jcr-mock.html
@RunWith(PowerMockRunner.class)
@PrepareForTest({UserNotificationListener.class})
public class UserNotificationListenerTest {
@InjectMocks
private UserNotificationListener userNotificationListener;
@Mock
private SlingRepository repository;
@test
public void testActivate() throws Exception {
// get details here for activate
Session session = mock(Session.class);
Workspace workspace = mock(Workspace.class);
ObservationManager observationManager = mock(ObservationManager.class);
when(repository.loginService(JcrSessionService.QUERY_SESSION_SERVICE.getService(), null)).thenReturn(session);
when(repository.getDescriptor(Repository.OPTION_OBSERVATION_SUPPORTED)).thenReturn("true");
when(session.getWorkspace()).thenReturn(workspace);
when(workspace.getObservationManager()).thenReturn(observationManager);
userNotificationListener.activate();
verify(observationManager).addEventListener(userNotificationListener, <<<Event.NODE_ADDED>>>, "/<<PATH>>/", true, null, types, true);
}
@test
public void testDeactivate() throws Exception {
// get details here for activate
Session session = mock(Session.class);
Workspace workspace = mock(Workspace.class);
ObservationManager observationManager = mock(ObservationManager.class);
when(repository.loginService(JcrSessionService.QUERY_SESSION_SERVICE.getService(), null)).thenReturn(session);
when(repository.getDescriptor(Repository.OPTION_OBSERVATION_SUPPORTED)).thenReturn("true");
when(session.getWorkspace()).thenReturn(workspace);
when(workspace.getObservationManager()).thenReturn(observationManager);
userNotificationListener.deactivate();
verify(<<<>>>>);
}
@test
public void testOnEvent() throws Exception {
EventIterator eventIterator = mock(EventIterator.class);
when(eventIterator.hasNext()).thenReturn(true).thenReturn(false);
Event event = mock(Event.class);
when(eventIterator.nextEvent()).thenReturn(event);
<<<<< remaining steps >>>>
}
}
Views
Replies
Total Likes
The cleanest way to unit test this is to simply test is an OSGi service using AEM Mocks [1] (which are a super-set of Sling Mocks/JCR mocks [2]).
You can see how something (of similar complexity, though a servlet) is achieved via this unit test [3]
Basically you'll need to:
1. Create a Unit Test using Mockito and AEM Mocks
2. In the @Before method
2. In your test case, injectAndActivate an instance of your EventListener along w/ any OSGi config properties you want to test it with)
3. Then, using the OSGi mock context get that service back using the interface (you can optionally cast the service to your impl class if you want to discretely test methods that arent on the interface).
4. Then you can test the service.
Note that as mentioned on [2] - with JcrMocks "Observation events can be registered but are ignored" - so looks like you'll mock that context when you test onEvent(..).
FWIW I think you'll end up spending some time getting it all mocked up/tested -- you may find that you want to refactor your code to be more testable as well.
[1] https://wcm.io/testing/aem-mock/
[2] https://sling.apache.org/documentation/development/jcr-mock.html
you can try like this
public class UserNotificationListener implements EventListener {
@RunWith(PowerMockRunner.class)
@PrepareForTest({UserNotificationListener.class})
public class UserNotificationListenerTest {
@InjectMocks
private UserNotificationListener userNotificationListener;
@Mock
private SlingRepository repository;
@test
public void testActivate() throws Exception {
// get details here for activate
Session session = mock(Session.class);
Workspace workspace = mock(Workspace.class);
ObservationManager observationManager = mock(ObservationManager.class);
when(repository.loginService(JcrSessionService.QUERY_SESSION_SERVICE.getService(), null)).thenReturn(session);
when(repository.getDescriptor(Repository.OPTION_OBSERVATION_SUPPORTED)).thenReturn("true");
when(session.getWorkspace()).thenReturn(workspace);
when(workspace.getObservationManager()).thenReturn(observationManager);
userNotificationListener.activate();
verify(observationManager).addEventListener(userNotificationListener, <<<Event.NODE_ADDED>>>, "/<<PATH>>/", true, null, types, true);
}
@test
public void testDeactivate() throws Exception {
// get details here for activate
Session session = mock(Session.class);
Workspace workspace = mock(Workspace.class);
ObservationManager observationManager = mock(ObservationManager.class);
when(repository.loginService(JcrSessionService.QUERY_SESSION_SERVICE.getService(), null)).thenReturn(session);
when(repository.getDescriptor(Repository.OPTION_OBSERVATION_SUPPORTED)).thenReturn("true");
when(session.getWorkspace()).thenReturn(workspace);
when(workspace.getObservationManager()).thenReturn(observationManager);
userNotificationListener.deactivate();
verify(<<<>>>>);
}
@test
public void testOnEvent() throws Exception {
EventIterator eventIterator = mock(EventIterator.class);
when(eventIterator.hasNext()).thenReturn(true).thenReturn(false);
Event event = mock(Event.class);
when(eventIterator.nextEvent()).thenReturn(event);
<<<<< remaining steps >>>>
}
}
Views
Replies
Total Likes
Views
Likes
Replies
Views
Like
Replies