Today I was trying to create a node.js script to test a HTTP service but the test required multiple steps.   I gave it a try by using async module to "symplify" that code and that's the ugly code I came up with.
I'm not an expert in js/node, feel free to comment if I'm doing something wrong, I'm more than happy to learn.
(inflightSession and create are two helper functions that I have)
Test using node + jasmine:  
it("should accept valid sessionId", function(done) {
      async.waterfall([
          inflightSession,
          function(sessionId, callback) {
            create({ 'sessionId':sessionId }, callback);
          }
      ], function(error, response) {
          expect(response.statusCode).to.equal(200);
          done()
    });
  });
Same test using python + unittest:
def create_ok_test():
    session_id = inflight_session()
    response = create({ 'sessionId': session_id })
    assert_equals(200, response.status_code)
Same test using node ES6 generators (yield keyword):
it("should accept valid sessionId", function*() {
      var sessionId = yield inflightSession();
      var response = yield create({ 'sessionId': sessionId });
      expect(response.statusCode).to.equal(200);
  });
Honestly the code in python is way more readable than the existing node code, and still better even when comparing it with the new node generators.    Anway definitely looks like a promising way to move forward in the node community.   Some comments:
ES6 generators are available under a flag in node 0.11 and are supposed to be included in 0.12.
yield is a common keyword in other languages (i.e. python, C#) to exit from a function but keeping the state of that function so that you can resume the execution later.
function* is the syntax to define a generator function (a function using yield inside).
You need a runner supporting those generator functions (in this example jasmine needs to add support for it), basically calling the generator.next and waiting for the result (the result should be a promise or similar object) before calling generator.next again.
UPDATE: As I´m somehow forced to use node, I ended up creating a helper function and my tests are now like this
itx("should accept valid sessionId", inflightSession, function(sessionId, done) {
      create({ 'sessionId':sessionId }, function(error, response) {
          expect(response.statusCode).to.equal(200);
          done()
      });
});
With promises you can do something like this (pseudocode):
ResponderEliminarinflightSession
.then(function(sessionId) {
create({sessionId:sessionId});
)
.then(function(response) {
expect(response.statusCode.to.equal(200));
})
.then(done);
It is clearer than async, but not as clear/compact as its sequential alternative in python/java... and most people/libraries still use the callback style.
These two are good resources:
- http://strongloop.com/strongblog/promises-in-node-js-with-q-an-alternative-to-callbacks/
- https://github.com/kriskowal/q
With async is slightly more compact IMO, but I agree that promises can be easier to read. Thx for the comment, very useful.
ResponderEliminarThis is also interesting, based on coroutines https://github.com/visionmedia/co
ResponderEliminar