Stubbing with fluent-http

One thing I do quite often if to make sure I can lunch my application offline. For instance, my application needs to access an external system that is only available from my company network.

So if I'm offline, it just doesn't work. And I don't like my ideas to go on hold just because I'm not in front of my desk at work or because the remote service is down.

Normally I would launch an embedded something (usually jetty) and have it server my stuff. The trick is to save real results from the actual server in some files and then serve these files. It's a bit complex to configure but in the end it works.

I use Spring profiles to turn the fake mode on and off.

This time, I tried something different. I used fluent-http. It is a really lightweight web server that gets configured a bit like NodeJS would.

I'm quite happy about it so I thought I should share.

My first usage was to turn a kinda integration test into a unit test. So I have a test that used to call the real server and that is now calling my fake server. I can in fact launch it in both modes. That's useful to make sure my code it still compliant with the actual server implementation.

It looks like this:

@Beforepublic void setup() throws Exception {
if(fake) {
initFakeServer();
}
}

private void initFakeServer() {
server = new WebServer().configure(routes -> routes
.get("/api/stuff", requestContent("stuff.json")))
).start(9456);
}

@Afterpublic void tearDown() {
 if(fake) {
        server.stop();
    }
}

private Payload requestContent(String file) {
try {
String content = new String(Files.readAllBytes(Paths.get("src/test/data/stuff", file)), "UTF-8");
return new Payload("application/json;charset=UTF-8", content);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
Nice and sweet. Fluent-http can also serve static files directly based on the extension if you prefer. But you will then need to match your directory layout with was is normally served by the real server.

Two gotchas though:

  • The content type can normally be deduced from the filename extension. However, the json extension wasn't supported. I made a pull request that was merged today so it should be fixed soon
  • The dependencies in the maven pom file are a bit more fast than what I was expecting. It might clash with some of your. I'm currently excluding slf4j-simple. This one should probably be in scope provided in the code