Expand my Community achievements bar.

Guidelines for the Responsible Use of Generative AI in the Experience Cloud Community.
SOLVED

Null Pointer Exception in Servlet Testing which having OSGi configurations

Avatar

Level 2

Hi Guys,
I am new to AEM development and trying to create Junit(Version 4) test cases for my servlet. I am calling an external API and getting JSON data rates in response, during this i am using OSGi configurations for few api related information. I am getting null pointer exception during the test run. Can anyone help me what i am missing here, below are my servlet and test classes code.

Servlet:
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import com.services.RatesIntegrationService;
import com.google.gson.JsonArray;
import com.google.gson.JsonParser;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.HttpConstants;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import com.google.gson.JsonObject;
import org.osgi.framework.Constants;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@component(service = Servlet.class, property = {Constants.SERVICE_DESCRIPTION + "=Rates Servlet",
"sling.servlet.methods=" + HttpConstants.METHOD_POST, "sling.servlet.paths=" + "/services/rates/"
})
public class RatesServlet extends SlingAllMethodsServlet {
String apiURL=null;
String tokenApiURL=null;
String secret=null;
String appID=null;
@reference
private RatesIntegrationService ratesIntegrationService;
protected final Logger log = LoggerFactory.getLogger(RatesServlet.class);
private static final String scope = "/**/communications::POST";
private String token;
@Override
protected void doPost(final SlingHttpServletRequest req, final SlingHttpServletResponse resp)
throws ServletException, IOException {
apiURL= ratesIntegrationService.getApiURL();
tokenApiURL = ratesIntegrationService.getTokenApiURL();
secret = ratesIntegrationService.getSecret();
appID = ratesIntegrationService.getAppID();
try {
generateToken(req);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
String market = req.getParameter("market");
TimeZone tz = TimeZone.getTimeZone("UTC");
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); // Quoted "Z" to indicate UTC, no timezone offset
df.setTimeZone(tz);
String nowAsISO = df.format(new Date());
CloseableHttpClient client = HttpClients.createDefault();
HttpPost method = new HttpPost(this.apiURL);
JsonObject json = new JsonObject();
json.addProperty("market", market);
json.addProperty("rateVarianceTimestamp", nowAsISO);
StringEntity entity = new StringEntity(json.toString(), ContentType.APPLICATION_JSON);
method.setEntity(entity);
String authorizationHeader="claims app_authorization="+String.valueOf(this.token);
method.setHeader("Content-Type", "application/json");
method.setHeader("app-id", this.appID);
method.setHeader("Authorization", authorizationHeader);
try {
CloseableHttpResponse response = client.execute(method);
System.out.println(response);
String ratesVarianceResponse = EntityUtils.toString(response.getEntity());
resp.setContentType("application/json");
resp.getWriter().write(ratesVarianceResponse);
} catch (Exception e) {
log.error("Exception in servlet while executing :", e.getMessage());
e.printStackTrace();
} finally {
method.releaseConnection();
}
}

}


Test Class:

package com.servlets;
import com.services.RatesIntegrationService;
import com.services.config.RatesIntegrationServiceConfig;
import com.services.impl.RatesIntegrationServiceImpl;
import io.wcm.testing.mock.aem.junit.AemContext;
import org.apache.sling.testing.mock.sling.ResourceResolverType;
import org.apache.sling.testing.mock.sling.junit.SlingContext;
import org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletRequest;
import org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletResponse;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import javax.servlet.ServletException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class RatesServletTest {
@Deleted Account
public final AemContext aemContext = new AemContext(ResourceResolverType.JCR_MOCK);
@InjectMocks
private RatesServlet testServlet;
@Mock
private MockSlingHttpServletRequest mockSlingRequest;
@Mock
private MockSlingHttpServletResponse mockSlingResponse;
@Mock
private RatesIntegrationService ratesIntegrationService;
@InjectMocks
private RatesIntegrationServiceImpl ratesIntegrationServiceImpl;
private Map<String, String> configProps = new HashMap<String, String>();
private Map<String, Object> parameterMap = new HashMap<String, Object>();
@Before
public void setUp() throws Exception {
ratesIntegrationServiceImpl=aemContext.registerService(new RatesIntegrationServiceImpl());
RatesIntegrationServiceConfig config=mock(RatesIntegrationServiceConfig.class);
when(config.apiURL()).thenReturn("https://api-domain.com");

when(config.secret()).thenReturn("AvnoqId=");
when(config.appID()).thenReturn("94b5fba");
ratesIntegrationServiceImpl.activate(config);
}
@test
public void doPostTest() throws ServletException, IOException {
parameterMap.put("market", "UK");
mockSlingRequest.setParameterMap(parameterMap);
testServlet.doPost(mockSlingRequest, mockSlingResponse);
assertEquals("application/json", mockSlingResponse.getContentType());
assertEquals(200, mockSlingResponse.getStatus());
assertTrue(mockSlingResponse.getOutputAsString().contains("UK"));
}
}

1 Accepted Solution

Avatar

Correct answer by
Level 4

Hi @siva_k222 ,

Instead of having when for config.apiUrl have when then for ratesIntegrationServiceImpl.getApiUrl and similarly for other variables.

Thanks!

View solution in original post

2 Replies

Avatar

Correct answer by
Level 4

Hi @siva_k222 ,

Instead of having when for config.apiUrl have when then for ratesIntegrationServiceImpl.getApiUrl and similarly for other variables.

Thanks!