Expand my Community achievements bar.

Mocking HTTP Clients in AEM Projects | AEM Community Blog Seeding

Avatar

Administrator

BlogImage.jpg

Mocking HTTP Clients in AEM Projects by perficient

Abstract

The first thing I learned as an AEM developer was mvn clean install -P autoInstallBundle. The second thing was how to debug a remote Java process. The first allowed me to deploy updates I made to the bundle. The second allowed me to step through and debug the code. This was the normal cadence.

Since then, the AEM Maven Archetype has evolved to include JUnit 5 with wcm.io AEM Mocks. That sits on top of the Sling Mock APIs. With JUnit and the AEM Mocks, I have been able to switch from a build/deploy/debug cadence to a test-driven one. This includes resources, servlets, pages, tags, context-aware configurations, models, and OSGi components. You name it. You can hit about 90% of the use cases you might encounter during AEM OSGi bundle development.
This blog is not about 90%. I’m sure you can find a lot of examples out there. This is about that 10%, in particular with HTTP clients. Right out of the box, AEM comes with the Apache HTTP Client. If you are running AEM under Java 11, its HttpClient is an option as well. Either way, you face the same problem. How do you mock constructors and static classes?

A Simple Example
Let us use this servlet as a real simple example.

@Component(service = { Servlet.class })
@SlingServletResourceTypes(resourceTypes = NameConstants.NT_PAGE,
methods = HttpConstants.METHOD_GET,
selectors = "proxy",
extensions = "json")
@Designate(ocd = ProxyServlet.Configuration.class)
public final class ProxyServlet extends SlingSafeMethodsServlet {
private static final long serialVersionUID = -2678188253939985649L;
@Activate
private transient Configuration configuration;
@Override
protected void doGet(final SlingHttpServletRequest request, final SlingHttpServletResponse response) throws IOException {
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
final HttpUriRequest httpRequest = new HttpGet(this.configuration.uri());
try (CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse httpResponse = httpClient.execute(httpRequest)) {
httpResponse.getEntity()
.writeTo(response.getOutputStream());
}
}
@ObjectClassDefinition
public @interface Configuration {
@AttributeDefinition String uri() default "https://randomuser.me/api/?results=1&inc=id,email,name,gender&seed=9579cb0f52986aab&noinfo";
}
}
It is your standard run-of-the-mill OSGi R7 servlet. It fetches data from some other API and proxies it back. If you have a keen eye, you have already spotted the problems. The HttpGet constructor and the HttpClients utility class. Half of you out there are thinking PowerMock. The other half are thinking about refactoring to make the code better suited for unit tests.

Read Full Blog

Mocking HTTP Clients in AEM Projects

Q&A

Please use this thread to ask the related questions.



Kautuk Sahni
Topics

Topics help categorize Community content and increase your ability to discover relevant content.

0 Replies