Yesterday I managed to get a simple Dart test server running for the purposes of unit testing
HttpRequest
code. Emphasis on the word simple. All that it does is return a JSON string regardless of the request.Today, I would like to test POSTing and possibly PUTting updates. To accomplish this, I am going to need to be able to persist data in my test server. I could do this in memory, but I have a quick and dirty way to do this already. So I add dart dirty as a dependency (along with UUID for IDs) to the list of dependencies in the library I am trying to test:
name: hipster_mvc version: 0.2.6 description: Dart-based MVC framework author: Chris StromA quickhomepage: https://github.com/eee-c/hipster-mvc dependencies: unittest: any dirty: any uuid: any js: any
pub update
and I have my quick and dirt noSQL database ready to go:➜ hipster-mvc git:(http-test-server) ✗ pub update Resolving dependencies......... Dependencies updated! ➜ hipster-mvc git:(http-test-server) ✗ ls packages browser dirty hipster_mvc js meta unittest uuidI would like to be able to write a test along the lines of:
test("it can POST new records", (){
_test(response) {
expect(response, {'test': 42});
}
var model = new FakeModel();
model.url = 'http://localhost:31337/widgets';
model.attributes = {'test': 42};
HipsterSync.call('create', model).then(expectAsync1(_test));
});
I am creating a fake model which is attempting to persist data in Hipster MVC at the /widgets
path on my test server. I expect that when I POST / create data that the server will reply back to me with the contents that I have created:{'test': 42}
.I need to start building out my test server to support this, so I add the necessary
import
statements along with a handler for the /widgets
path:import 'dart:io'; import 'dart:json' as JSON; import 'package:dirty/dirty.dart'; import 'package:uuid/uuid.dart'; main() { var port = Platform.environment['PORT'] == null ? 31337 : int.parse(Platform.environment['PORT']); HttpServer.bind('127.0.0.1', port).then((app) { app.listen((HttpRequest req) { if (req.uri.path.startsWith('/widgets')) { handleWidgets(req); return; } defaultResponse(req); }); }); }To handle the
/widgets
, I need to determine the HTTP verb that is being used to make the request. I also need to know if the request includes an ID or not:handleWidgets(req) { var r = new RegExp(r"/widgets/([-\w\d]+)"); var id_path = r.firstMatch(req.uri.path), id = (id_path == null) ? null : id_path[1]; if (req.method == 'POST') return createWidget(req); if (req.method == 'GET' && id != null) readWidget(req); notFoundResponse(req); }I will add more over the next few days, but that is a decent start. Now, I need to be able to create widgets in the persisted DB:
createWidget(req) { HttpResponse res = req.response; Uuid uuid = new Uuid(); Dirty db = new Dirty('test.db'); req.toList().then((list) { var post_data = new String.fromCharCodes(list[0]); var widget = JSON.parse(post_data); widget['id'] = uuid.v1(); db[widget['id']] = widget; res.statusCode = 201; res.headers.contentType = new ContentType("application", "json", charset: "utf-8"); res.write(JSON.stringify(widget)); res.close(); }); }I am probably trying to do too much in there. I am reading the body of the request for the POSTed JSON data. Then I turn around and fashion a response. At the same time, I am writing to the test DB. As I said, I could probably clean that up, but it will do for now—at least as a test server.
With that, I have my test passing, but I still have a problem: the test DB is sticking around:
➜ hipster-mvc git:(http-test-server) ✗ cat test/test.db {"key":"962c9aa0-c9c0-11e2-9027-23f0a97992d8","val":{"test":42,"id":"962c9aa0-c9c0-11e2-9027-23f0a97992d8"}}I will explore teardown HTTP paths tomorrow, but for now, I manually remove this in my continuous integration script:
echo "starting test server" dart test/test_server.dart & server_pid=$! echo "content_shell --dump-render-tree test/index.html" results=`content_shell --dump-render-tree test/index.html 2>&1` # ... kill $server_pid rm -f test/test.db # ...That seems a decent stopping point for tonight. Setting up the server and the “routing” was a bit more challenging that I had expected (I keep thinking that I have finally found a use for
case
statements in Dart only to be proven wrong). Still, this seems promising for testing the remainder of Hipster MVC's RESTful routing methods, which I hope to finish off tomorrow.Day #804
No comments:
Post a Comment