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:
@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) {
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");
}
@test
void doGet() {
SlingHttpServletRequest request = context.request();
SlingHttpServletResponse response = context.response();
HubSourceServlet.doGet(request,response);
assert (true);
}
}
Solved! Go to Solution.
Views
Replies
Total Likes
Try this in your setup method
context.registerService(RestAPIConfigurations.class, restAPIConfigurations);
Try this in your setup method
context.registerService(RestAPIConfigurations.class, restAPIConfigurations);
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());
}
}
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.