AEM servlet JUNIT 5 help | Community
Skip to main content
Level 3
June 17, 2024
Solved

AEM servlet JUNIT 5 help

  • June 17, 2024
  • 3 replies
  • 960 views

Hi Team,

 

I am trying to write JUNIT5 test code for below servlet. I am stuck and not  able to proceed further. When I debug Test Class and it takes me to doGet Method of servlet,It always gives me NULL pointer Exception for RestAPIConfigurations service(). Highlighted in Blue Color.

Below are servlet and JUNIT code.

Any help will be  appreciated.

SERVLET CODE:

@8220494(service = Servlet.class, property = {
Constants.SERVICE_ID + "=Dynamic DataSource Servlet",
SLING_SERVLET_METHODS + "=" + HttpConstants.METHOD_GET,
SLING_SERVLET_RESOURCE_TYPES + "=mysite/product/details"
})
public class HubSourceServlet extends SlingSafeMethodsServlet {
private static final String TAG = HubSourceServlet.class.getSimpleName();
private static final Logger LOGGER = LoggerFactory.getLogger(HubSourceServlet.class);

@3214626
RestAPIConfigurations restAPIConfigurations;

@9944223
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) {
try {
ResourceResolver resourceResolver = request.getResourceResolver();
String domainName = restAPIConfigurations.getDomain();
LOGGER.debug(TAG, domainName);

Resource currentResource = request.getResource();
String selector = Objects.requireNonNull(currentResource.getChild("datasource")).getValueMap().get("selector", String.class);
String jsonData = StringUtils.EMPTY;
boolean fifthLevelFlag = true;
if(null != selector && StringUtils.equals("news", selector)){
fifthLevelFlag = false;
}
if(null != selector && StringUtils.equals("articles",selector)){
LOGGER.info("selector in HubSourceServlet is :",selector);
jsonData = getData(domainName+"/api/v1/REST/articles-groups");
}
else {

jsonData = getData(domainName+"/api/v1/REST/news-groups");
}

JSONArray data = new JSONArray(jsonData);

DataSource ds = new SimpleDataSource(getValueMapResource(data, resourceResolver));

request.setAttribute(DataSource.class.getName(), ds);
} catch (IOException | JSONException e) {
}
}

public String getData(String path) throws IOException {

TrustManager[] trustAll= new TrustManager[] {
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}

public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}

public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
}
};
SSLContext sc = null;
try {
sc = SSLContext.getInstance("SSL");
sc.init(null, trustAll, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
e.printStackTrace();
}

InputStream is = null;
String content = null;
try {

LOGGER.info("In HubSourceServlet getData url: {}", path);
URL urlObj = new URL(path);
String auth = restAPIConfigurations.getUserName() + ":" + restAPIConfigurations.getPassName();
byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes(StandardCharsets.UTF_8));
String authHeaderValue = "Basic " + new String(encodedAuth);
HttpURLConnection httpURLConnection = (HttpURLConnection) urlObj.openConnection();
httpURLConnection.setRequestProperty("Authorization", authHeaderValue);

httpURLConnection.setRequestMethod("GET");
is = httpURLConnection.getInputStream();
content = IOUtils.toString(is, StandardCharsets.UTF_8);
LOGGER.info("In HubSourceServlet getData content: {}", content);
} finally {
IOUtils.closeQuietly(is);
}

return content;
}
public void setrestAPIConfigurations(restAPIConfigurations restAPIConfigurations) {
this.restAPIConfigurations = restAPIConfigurations;
}
}

 

JUNIT CLASS:

@ExtendWith(AemContextExtension.class)
@ExtendWith(MockitoExtension.class)
class HubSourceServletTest {

private final AemContext context = AppAemContext.newAemContext();

private static HubSourceServlet HubSourceServlet;

private static JSONArray data;

private static String domainName;

@Mock
private static RestAPIConfigurations restAPIConfigurations;

@Mock
private static Resource currentResource;

@Mock
private ResourceResolver resourceResolver;

@BeforeAll
public static void setUp() {
HubSourceServlet = new HubSourceServlet();

}
@BeforeEach
public void setUpBefore() {
when(restAPIConfigurations.getDomain()).thenReturn("mydomain");
}

@2785667
void doGet() {
SlingHttpServletRequest request = context.request();
SlingHttpServletResponse response = context.response();
HubSourceServlet.doGet(request,response);

assert (true);
}
}

 

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.
Best answer by h_kataria

Try this in your setup method

context.registerService(RestAPIConfigurations.class, restAPIConfigurations);



3 replies

h_kataria
Community Advisor
h_katariaCommunity AdvisorAccepted solution
Community Advisor
June 17, 2024

Try this in your setup method

context.registerService(RestAPIConfigurations.class, restAPIConfigurations);



kapil_rajoria
Community Advisor
Community Advisor
June 17, 2024

Hi @arvindpandey , Please refer below working code:

 

//---RestAPIConfigurations.java--- public interface RestAPIConfigurations { String getDomain(); } //---RestAPIConfigurationsImpl.java--- @Component(immediate = true, service = RestAPIConfigurations.class) @Designate(ocd = RestAPIConfigurationsImpl.Configs.class) public class RestAPIConfigurationsImpl implements RestAPIConfigurations { private String domainName; @Activate @Modified public void activate(Configs configs) { domainName = configs.domainName(); } @ObjectClassDefinition(name = "keys", description = "keys") public @interface Configs { @AttributeDefinition(name = "Url", description = "Url") String domainName(); } @Override public String getDomain(){return domainName;} } //---HubSourceServlet.java--- @Component(service = Servlet.class, property = { Constants.SERVICE_ID + "=Dynamic DataSource Servlet", SLING_SERVLET_METHODS + "=" + HttpConstants.METHOD_GET, SLING_SERVLET_RESOURCE_TYPES + "=mysite/product/details" }) public class HubSourceServlet extends SlingSafeMethodsServlet { private static final String TAG = HubSourceServlet.class.getSimpleName(); private static final Logger LOGGER = LoggerFactory.getLogger(HubSourceServlet.class); @Reference RestAPIConfigurations restAPIConfigurations; @Override protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException { String domainName = restAPIConfigurations.getDomain(); request.setAttribute(domainName,String.class); } } //---HubSourceServletTest.java--- @ExtendWith(MockitoExtension.class) class HubSourceServletTest { @InjectMocks HubSourceServlet hubSourceServlet; @Mock SlingHttpServletRequest slingRequest; @Mock SlingHttpServletResponse slingResponse; @Mock RestAPIConfigurationsImpl.Configs restAPIConfigurations; @Mock private RestAPIConfigurationsImpl restAPIConfigurationsImpl; @Test void doGet() { when(restAPIConfigurationsImpl.getDomain()).thenReturn("test"); assertEquals("test",restAPIConfigurationsImpl.getDomain()); } }

 

 

PGURUKRISHNA
Level 4
June 17, 2024

Hi @arvindpandey 

From what I can see, the issue is that the restAPIConfigurations service is not being injected into your servlet instance in the test class.

In your test class, you have mocked the RestAPIConfigurations service, but you haven't injected it into the HubSourceServlet instance.

Here's how you can fix it:

@ExtendWith(AemContextExtension.class)
@ExtendWith(MockitoExtension.class)
class HubSourceServletTest {

private final AemContext context = AppAemContext.newAemContext();

private static HubSourceServlet hubSourceServlet;

private static JSONArray data;

private static String domainName;

@Mock
private static RestAPIConfigurations restAPIConfigurations;

@Mock
private static Resource currentResource;

@Mock
private static ResourceResolver resourceResolver;

@BeforeAll
public static void setUp() {
hubSourceServlet = new HubSourceServlet();
hubSourceServlet.setrestAPIConfigurations(restAPIConfigurations); // inject the mock service
}

@BeforeEach
public void setUpBefore() {
when(restAPIConfigurations.getDomain()).thenReturn("mydomain");
}

@Test
void doGet() {
SlingHttpServletRequest request = context.request();
SlingHttpServletResponse response = context.response();
hubSourceServlet.doGet(request,response);

assert (true);
}
}

By calling hubSourceServlet.setrestAPIConfigurations(restAPIConfigurations) in the @BeforeAll method, you're injecting the mocked RestAPIConfigurations service into the HubSourceServlet instance.

This should fix the NullPointerException you're seeing when you debug the test class and it takes you to the doGet method of the servlet.