Logo

dev-resources.site

for different kinds of informations.

[HttpServer series] Testing the server

Published at
1/10/2024
Categories
java
learning
frameworks
Author
mandraketech
Categories
3 categories in total
java
open
learning
open
frameworks
open
Author
12 person written this
mandraketech
open
[HttpServer series] Testing the server

As I started the journey down the test route, the first thought was to unit test the individual Handlers. This required the implementation of a HttpExchange object. As I delved into the specific APIs to be implemented for a MockHttpExchange it turned out that there is a specific set of sequence the APIs should be called. As per the documentation, the sendResponseHeaders needs to be called before the getResponseBody stream. But, in the actual implementation in the JRE, that need not be the case. So, my Mocks broke my implementation that works in production. Hah !!!

Then I looked at testing the registration of the endpoints, and that lead me to implement a MockHttpServer that would accept the context registrations. Again, implementing that API felt like I was not getting any testing done really. Everything was in my mock, so the production would feel very different, and possibly break.

So, I dropped the "unit test", and worked on the integration test. My tests bring up an Http Server in the test environment, hit the 2 APIs ( ping and 404, for everything else) that have been implemented, and stop the server after that.

I am fairly satisfied with this approach for now. It allows me to move on to the next step.

The test looks like this:

class PingAndRootEndpointTest { static App app; static final int PORT = 9090; static String baseAddress = "http://localhost:%d".formatted(PORT); @BeforeAll public static void initializeApp() throws IOException { app = new App(PORT); app.start(); } @AfterAll public static void stopApp() { app.stop(0); app = null; } @Test void testPingHandler() throws IOException, InterruptedException { var client = HttpClient.newHttpClient(); var uri = URI.create("%s/%s".formatted(baseAddress, "ping")); var response = client.send( HttpRequest.newBuilder().GET().uri(uri).build(), BodyHandlers.ofString()); assertEquals(200, response.statusCode()); assertEquals("pong", response.body()); } @Test void testRootHandler() throws IOException, InterruptedException { var client = HttpClient.newHttpClient(); var uri = URI.create("%s/%s".formatted(baseAddress, "404")); var response = client.send( HttpRequest.newBuilder().GET().uri(uri).build(), BodyHandlers.ofString()); assertEquals(404, response.statusCode()); assertEquals("Not Found !!!", response.body()); } }
Enter fullscreen mode Exit fullscreen mode

The code for the tests are in this Merge Request: https://gitlab.com/mandraketech/httpserver-based-todo-app/-/merge_requests/5

Yeah, I know, Annotations. These are for Junit 5. And there is no way to avoid them. Thankfully, they do not add anything to the class files. Only used for lookup using reflection, when running them.

I did not know about IntegrationTests, or IT, plugin called Maven Failsafe at the time I merged the request. Will rename the test at an appropriate time and integrate this plugin too. Need to be able to differentiate between Unit Tests and Integration Tests.

Along the way, I got some cleanup, and simplifications on the Docker images, for dev as well as prod environments. They now use the alpine versions of the JRE, and VSCode is happy working in them. So, I just trimmed down the release image to under 300MB, down from over 600 earlier. The dev environment is down from over 900 MB earlier to under 600MB too. The changes are in the (https://gitlab.com/mandraketech/java-vscode-dev) if you want to take from there.

We have "Water Though the Pipe" now, and the learnings from these are as follows:

  • The HttpServer "context" can be used to wire up separate processing units, but each context will need a "Router" for itself, just like all the other frameworks. For example, creating a context handler for serving static files, and another for endpoints that server JSON, vs those that server html / templates.

  • This will require writing a basic router that can handle the Todo endpoints. Given that the HttpServer context exposes the very fundamental constructs, it will help if we can wrap up the request, response and some request context into the handler api. This will allow cleanly handling any error conditions, and ensuring that the response stream is not polluted in the handler.

  • This will also allow us to write "preprocessors" or "middleware" to handle security, sanitising the request, and similar activities.

  • I will look for inspiration in the implementation to the Servlet API, and the Fastify framework ( Node ecosystem ).

It has been quite a journey so far. Until next time.

frameworks Article's
30 articles in total
Favicon
JavaScript Frameworks - Heading into 2025
Favicon
Unlocking the Power of Django: Build Secure and Scalable Web Apps Fast
Favicon
The Best Web Development Frameworks in 2024
Favicon
Why Django Stands Out Among Web Development Frameworks
Favicon
Top JavaScript Frameworks to Master in 2024
Favicon
Fixing CORS in your SPA
Favicon
Demasiados frameworks de JS, pero por qué?
Favicon
Who's Your .NET Ally? - F# vs C#
Favicon
Angular vs React: A Frontend Showdown
Favicon
How To Install TestNG in Eclipse: Step By Step Guide
Favicon
Integrating Laravel with Popular Frontend Frameworks: A Developer's Guide
Favicon
This Month in Solid #4: The Shape of Frameworks to Come 😎
Favicon
So many JS frameworks, but why?
Favicon
Why Core Knowledge in HTML, CSS, JavaScript, and PHP is Timeless
Favicon
Frontend Frameworks from 2023-2024
Favicon
Java GUI Frameworks: Some go for these fine tools
Favicon
Spring Boot vs Quarkus: Pick one for Java
Favicon
[HttpServer Series] Authentication and Role based Authorization (RBAC)
Favicon
Stuck in the Middle with You: An intro to Middleware
Favicon
Sempre vale apena usar Frameworks?
Favicon
Navigating the Frontiers of Web Development:A Deep Dive into Framework Wars
Favicon
Best Frameworks For Cross-Platform App Development
Favicon
[HttpServer series] Static File server, and Logging
Favicon
[HttpServer Series] The Http Router - from scratch - in Java
Favicon
Webinar De COBIT Para Governança de TI Gratuito da KA Solution
Favicon
[HttpServer series] Testing the server
Favicon
[HttpServer series] Getting Started - First context (endpoint)
Favicon
JavaScript Frameworks - Heading into 2024
Favicon
[HttpServer series] Setting up the dev environment
Favicon
[HttpServer series] Will it support the Performance, and Scale ?

Featured ones: