fadedbee
fadedbee

Reputation: 44807

Mocha: How to test a series of async operations, which must be tested in sequence

Is the following test the best way to do this, or can I improve this (and remove the Step dependency)?

I am particularly concerned that each "step" function conflates the testing of the previous execution with the invocation of the next execution. (i.e. cut-and-paste fragile)

(Also see: How can I execute async Mocha tests (NodeJS) in order? )

  it('should run an update', function(done) {
    var db = new database.Database();
    var sess = new session.Session(db);
    Step(
      function createTable() {
        sess.exec('create table customers (id integer primary key auto_increment, name varchar, age integer)', this);
      },
      function insertCustomer1(err, message) {
        assert(!err, err);
        assert.equal("Table created.", message);
        sess.exec('insert into customers (name, age) values ("james", 41)', this);
      },
      function insertCustomer2(err, message) {
        assert(!err, err);
        assert.equal("1 row inserted.", message);
        sess.exec('insert into customers (name, age) values ("thomas", 19)', this);
      },
      function updateCustomer1(err, message) {
        assert(!err, err);
        assert.equal("1 row inserted.", message);
        sess.exec('update customers set age = 42 where name = "james"', this);
      },
      function end(err, message) {
        assert(!err, err);
        assert.equal("1 row updated.", message);
        done();
      }

    );
  });

Upvotes: 0

Views: 870

Answers (1)

Beau
Beau

Reputation: 11378

To solve the conflation issue you could write the code like this:

Step(
  function createTable() {
    var next = this;
    sess.exec('create table customers (id integer primary key auto_increment, name varchar, age integer)', function (err, message) {
      assert(!err, err);
      assert.equal("Table created.", message);

      next();
    });
  },
  function insertCustomer1() {
    var next = this;
    sess.exec('insert into customers (name, age) values ("james", 41)', function (err, message) {
      assert(!err, err);
      assert.equal("1 row inserted.", message);

      next();
    });
  },

I believe you'll need to set var next = this because Step uses this as the callback for asynchronous steps and it won't be bound correctly in the call to sess.exec. If that's a dealbreaker (less boilerplate is better, in my opinion) you might look at using async#series.

Upvotes: 1

Related Questions