I have a hacky unit test in place for some early code from Dart for Hipsters. Rather unfortunately, this involves jamming a conditional-behavior
HttpRequest
class directly in production code. Ultimately, this code evolves into Hipster MVC, which allows the data sync layer to be injected as a matter of course. Testing will be easy there. But what happens when I try to test the code after the initial implementation and before the injection class? Hopefully I might learn a better way of doing this.In the book, I move the
HttpRequest
code out into something of a MVC collection. The code is identical to the fully inline code used before refactoring with one small exception:class ComicsCollection implements Collection { // ... void fetch() { var req = new HttpRequest(); req.on.load.add((event) { var list = JSON.parse(req.responseText); _handleOnLoad(list); }); // verb, resource, boolean async req.open('get', url, true); req.send(); } }The difference is the
_handleOnLoad()
private method. In the original implementation, this had simply built HTML for the page, which could be immediately tested. Now, I build a bunch of models based on the JSON and dispatch a load event: _handleOnLoad(list) {
list.forEach((attrs) {
var new_model = new ComicBook(attrs);
new_model.collection = this;
models.add(new_model);
});
on.load.dispatch(new CollectionEvent('load', this));
}
Eventually that load event reaches the necessary view, which draws the individual elements on the page.I can play the same trick of my code that I did yesterday, replacing
HttpRequest
in that fetch()
method with my custom built MaybeMockHttpRequest
. By default, that uses the real HttpRequest
, so my sample app still runs. Some well placed setUp()
code in my tests insert a fake HttpRequest
and response: setUp((){
Main.MaybeMockHttpRequest.use_mock = true;
Main.MockHttpRequest.responseText = """
[{"id":"42", "title": "Sandman", "author":"Neil Gaiman"}]
""";
document.body.append(el);
});
test('populates the list', (){
Main.main();
expect(el.innerHtml, contains('Sandman'));
});
With that, I have a passing test:It is encouraging that this
MaybeMockHttpRequest
approach still works in the modified code. I have a bit more confidence in sticking with this approach—at least to keep the code in my book under test.At the same time, it still feels wrong. I should not have to resort to fake class hackery in live code just to test my code. I might claim that Dart wants dependency injected
HttpRequest
layers by virtue of difficulty testing any other way—I did eventually factor this code out into a testable sync layer. But that seems a cop out—I ought to be able to test vanilla HttpRequest
code.Part of the problem is definitely me. I am trying to perform (nearly) full stack integration testing with a unit testing library. Maybe I should live with a bit of hackery. Or maybe I need to embrace the insanity and fire up a test server so that I can truly test the entire stack. Tomorrow.
Day #611
This comment has been removed by the author.
ReplyDelete