Expand my Community achievements bar.

Don’t miss the AEM Skill Exchange in SF on Nov 14—hear from industry leaders, learn best practices, and enhance your AEM strategy with practical tips.
SOLVED

Junit5 test case for accesscontrolManager functionality throws excpeption

Avatar

Level 2

This test case throws unsupported exception when using the JUNIT5 version as per below

I am instantiating the aem context at class level with below code

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

class TrashcanServletTest {

 

private final AemContext aemContext = new AemContext(ResourceResolverType.JCR_MOCK);

 

Testcase method is provided here :

 

void testDoGetSlingHttpServletRequestSlingHttpServletResponse() throws UnsupportedRepositoryOperationException, RepositoryException {

 

aemContext.create().page("/content/ey-unified-site/language-masters/en/blueprintpage2/page1", "/", "We Retail");

MockSlingHttpServletRequestmockSlingRequest = aemContext.request();

MockSlingHttpServletResponsemockSlingResponse = aemContext.response();

Resource payloadResource = mockSlingRequest.getResourceResolver().resolve("/content/ey-unified-site/language-masters/en/blueprintpage2/page1");

ResourceResolver rr = payloadResource.getResourceResolver();

    Session session = rr.adaptTo(Session.class);

    final AccessControlManager accessControlManager = session.getAccessControlManager();

    final Privilege moveToTrashCanPrivilege = accessControlManager.privilegeFromName(Privilege.JCR_REMOVE_NODE);

    if(accessControlManager.hasPrivileges(payloadResource.getPath(), new Privilege[]{moveToTrashCanPrivilege})) {

            //todo use full work

        }

 

This line-->     final AccessControlManager accessControlManager = session.getAccessControlManager(); throws java.lang.UnsupportedOperationException

 

Where as I found the test cases in below URL where JUNIT 4 class works

https://github.com/Adobe-Consulting-Services/acs-aem-commons/blob/master/bundle/src/test/java/com/ad...

 Mocking the accessControlMager using when() method also not resolving the issue as per below code:

Mockito.lenient().when(session.getAccessControlManager()).thenReturn(accessControlManager);

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

Hi @subramanya_75,

We need to

  • Mock the AccessControlManager and
  • In setUp()/@BeforeEach method, we need to write mock implementation - when(session.getAccessControlManager()).thenReturn(accessControlManager), as done in the code in Shared GITHUB path
    • Note : Junit5 equivalent for @Before is @BeforeEach
  • Use that mocked reference in the desired testMethod.

Per the code you have shared, problematic line is not using mocked AccessControlManager.

View solution in original post

6 Replies

Avatar

Correct answer by
Community Advisor

Hi @subramanya_75,

We need to

  • Mock the AccessControlManager and
  • In setUp()/@BeforeEach method, we need to write mock implementation - when(session.getAccessControlManager()).thenReturn(accessControlManager), as done in the code in Shared GITHUB path
    • Note : Junit5 equivalent for @Before is @BeforeEach
  • Use that mocked reference in the desired testMethod.

Per the code you have shared, problematic line is not using mocked AccessControlManager.

Avatar

Level 2

Hi @Vijayalaksmi_S,

I have marked the correct answer by mistake.

I have tried the method you have informed unfortunately it does not work.

I need to know if anyone got this issue and ableto resolve this issue.

The provided answer may work on JUNIT4 but not when using JUNIT5.

I request some one to reopen this question and get this resolved

Avatar

Community Advisor

@subramanya_75,

No worries. Can you share your complete test class if possible. 

In parallel, will try to reproduce in my local. 

 

@kautuk_sahni,

Could you please mark this thread as unresolved. 

Avatar

Level 2

I modified the code as per below

at class level I have add a class level mock like below

@Mock

Session  session;

 

Then in the test case wrapped this session using the SessionWrapper provided in URL mentioned earlier. below code works

 

SessionWrapper wrapper = new SessionWrapper(session)

assertSame("getAccessControlManager", accessControlManager, wrapper.getAccessControlManager());

    final AccessControlManager accessControlManager = session.getAccessControlManager();

    final Privilege moveToTrashCanPrivilege = accessControlManager.privilegeFromName(Privilege.JCR_REMOVE_NODE);

    if(accessControlManager.hasPrivileges(payloadResource.getPath(), new Privilege[]{moveToTrashCanPrivilege})) {

            //todo use full work

    }

 

Now the real problem is I am only passing my mocked resource to a method that actually runs above code. I need to test the method of an implementing class for which I am writing this test case.

This code session.getAccessControlManager(); is being executed in the class for which I am writing the test case, I have given this code only for illustration purposes here.

Hence I am clueless about how to implement  a test case for  an AEM source code classes's method that has the code that invokes session.getAccessControlManager(); and it throws UnsupportedMethodException.

How to make the accessControlManager available to the implementing class's method when I am passing the mocked resource as a parameter from my test class.

Avatar

Community Advisor

Hi @subramanya_75,

We need to instantiate the servlet (which we need to test) in ServletTest class and invoke its doGet(req, resp) method by setting MockSlingHttpServletRequest and MockSlingHttpServletResponse. 

And based on the logic you have implemented in actual doGet() method, we need to set them in AemContext or provide mock implementations for those lines of code in ServletTest class.

Is it possible for you to share the actual Servlet class. 

Avatar

Level 2

 

Everything works when code written in this test class.

Problem is occcurs when session.getAccessControlmanager() is executed in the doGet() method in the servlet for which I am  writing this  test case.

 

This is the code complete test case class for the servlet.( everything works in the testcase, but not when same code executed in servlet.

class TrashcanServletTest {

private final AemContext aemContext = new AemContext(ResourceResolverType.JCR_MOCK);
//public final SlingContext aemContext = new SlingContext(ResourceResolverType.JCR_OAK);


private Map<String, String> configProps = new HashMap<String, String>();

TrashcanServlet unitTestServletObj = new TrashcanServlet();

private Map<String, Object> parameterMap = null;

MockSlingSettingService settingService;
ResourceResolverFactory resolverFactory;

@Mock
AccessControlManager accessControlManager;

@Mock
MockitoSession mockitosession;

@Mock
Session session;

@Mock
ResourceResolver resourceResolver;

 

@BeforeEach
void setUp() throws Exception {

settingService = (MockSlingSettingService) aemContext.getService(SlingSettingsService.class);
resolverFactory = aemContext.getService(ResourceResolverFactory.class);
Set<String> runModes = new HashSet<>();
Collections.addAll(runModes, "author", "qa");
settingService.setRunModes(runModes);
unitTestServletObj.setSlingSettingsService(settingService);
unitTestServletObj.resolverFactory = resolverFactory;
unitTestServletObj.activate();


Mockito.lenient().when(session.getAccessControlManager()).thenReturn(accessControlManager);
}

@test
void testDoGetSlingHttpServletRequestSlingHttpServletResponse() throws Exception {

aemContext.create().page("/content/unified-site/language-masters/en/blueprintpage2/page1", "/", "We Retail");

MockSlingHttpServletRequest mockSlingRequest = aemContext.request();
MockSlingHttpServletResponse mockSlingResponse = aemContext.response();
Resource payloadResource = mockSlingRequest.getResourceResolver().resolve("/content/unified-site/language-masters/en/blueprintpage2/page1");
ResourceResolver rr = payloadResource.getResourceResolver();
//BaseSessionIWrap session =(BaseSessionIWrap) rr.adaptTo(Session.class);
SessionWrapper wrapper = new SessionWrapper(session);


assertSame("getAccessControlManager", accessControlManager, wrapper.getAccessControlManager());

final AccessControlManager accessControlManager = session.getAccessControlManager();
final Privilege moveToTrashCanPrivilege = accessControlManager.privilegeFromName(Privilege.JCR_REMOVE_NODE);
if(accessControlManager.hasPrivileges(payloadResource.getPath(), new Privilege[]{moveToTrashCanPrivilege})) {
//todo use full work
}

String requestJson = "{\"action\":\"trash\",\"items\":[{\"source\":\"/content/unified-site/language-masters/en/blueprintpage2/page1\",\"target\":null}]}";
parameterMap = new HashMap<String, Object>();
parameterMap.put(requestJson,"request");
mockSlingRequest.setParameterMap(parameterMap);


if (null != unitTestServletObj && null != mockSlingRequest && null != mockSlingResponse) {
unitTestServletObj.doGet(mockSlingRequest, mockSlingResponse);});

}

}

static class SessionWrapper implements BaseSessionIWrap<Session> {
final Session wrapped;

public SessionWrapper(final Session wrapped) {
this.wrapped = wrapped;
}

@Override
public Session unwrapSession() {
return wrapped;
}
}

}