Many times when I'm writing JavaScript code with Ajax calls I don't have an
URL to call and get the data yet. Or sometimes I have an URL that gives me
valid data and I need to test the code against invalid data or some other
variation that I don't have handy.
WEBrick
In these situations, instead of creating a temporary ASP.NET application,
I learned to love using Ruby and the adorable simplicity of
WEBrick. Imagine that I needed
an URL that simulated latency on the server.
require 'webrick'
include WEBrick
server = HTTPServer.new( :Port => 2000 )
server.mount_proc("/getData"){|req, res|
res.body = "{result: 'ok', accountId: 123}"
res['Content-Type'] = "application/json"
delay = req.query['delay'] || "0"
sleep(delay.to_i)
}
trap("INT"){ server.shutdown }
server.start
After running the script I can open use the URL http://localhost:2000/getData?delay=5
in my Ajax call and, after a delay of five seconds, the JSON string {result: 'ok', accountId: 123}
will be returned. The server will stay there, in a console window, running until I kill it with CTRL+C.
I could add more mount points on that server for as many test URLs as I wish. I find this incredibly practical.
I wish there was something as simple in .NET
Well, I couldn't find anything as easy in .NET. The few offerings I found were not as straight forward. Some
of the alternatives are distributed in .msi files, which makes them less convenient, especially
for integration testing or JavaScript unit testing (which is my end goal.)
Hello Juicy
Envy sometimes makes you move forward. I played around with sockets and the HTTP protocol
and ended up with a library that looks promising. See that same code written using
the Juicy.DirtCheapDaemons.Http.HttpServer
class, a.k.a. the Juicy Web Server.
using System;
using System.IO;
using System.Threading;
using Juicy.DirtCheapDaemons.Http;
class Program
{
static void Main(string[] args)
{
HttpServer server = new HttpServer{ PortNumber = 2000 };
server.Start();
server.Mount("/getData",
(req, resp) =>
{
resp.Output.Write("{result: 'ok', accountId: 123}");
resp["Content-Type"] = "application/json";
var delay = int.Parse(req.QueryString["delay"] ?? "0");
Thread.Sleep(1000 * delay);
}
);
Console.WriteLine("Press enter to stop server");
Console.ReadLine();
server.Shutdown();
}
}
There are a few things more that can be done with HttpServer
.
//mounting virtual path with a lambda (shown in previous example)
server.Mount("/virtual/path", (req, resp) => DoSomethingWith(req, resp));
//mounting virtual path to serve static files
server.Mount("/virtual/path", @"c:\some\directory");
//hiding a virtual path
server.Mount("/virtual/path/subdir", new ResourceNotFoundHandler());
As it is, HttpServer
supports only GET requests.
The plan is to add more support (for features that make sense in a
unit testing scenario) with time.
I obviously don't envision Juicy becoming a full-fledged web server
that I can recommend using in a live web site. But I can see it
being helpful in the scenarios I've just described and for testing
in general.
I'm sold. Where can I get it?
This project is hosted at GitHub: http://github.com/sergiopereira/juicy/tree/master,
where you can download the source directly or even clone the repository :
c:\projects>git clone git://github.com/sergiopereira/juicy.git