Search code examples
javascripttestingbddmocha.jsrmdir

Mocha doesn't call rmdir in after() function


I try to create some tree of directories before tests and remove it after all:

require('should');
var fs = require('fs');
var rmdir = require('rmdir');

describe('FsWatcher', function() {
  before(function(done) {
    console.log("before");
    fs.mkdir('tmp');
    fs.mkdir('tmp/css');
    fs.mkdir('tmp/js');
    fs.mkdir('tmp/lib');
    fs.open('tmp/index.htm', 'w');
    // (...)
    console.log("after_before");
    done();
  });

  describe('single file', function() {
    it('should succed', function(done) {
      (1).should.equal(1);
      done();
    });
  });

  after(function() {
    console.log("after");
    rmdir('tmp', function() {
        console.log("rmdir!");
    });
    console.log("after_end");
  });
});

The order of console.logs is OK:

mocha `find tests -name '*.js'`

  before
after_before
․after
after_end


  ✔ 1 test complete (6 ms)

But it doesn't call rmdir(). The same rmdir works when it's at the end of before():

describe('FsWatcher', function() {
  before(function(done) {
    console.log("before");
    fs.mkdir('tmp');
    fs.mkdir('tmp/css');
    fs.mkdir('tmp/js');
    fs.mkdir('tmp/lib');
    fs.open('tmp/index.htm', 'w');
    // (...)
    console.log("after_before");
    rmdir('tmp', function(){
        console.log("rmdir!");
    });
    done();
  });
});

Console:

mocha `find tests -name '*.js'`

  before
after_before
 rmdir!
after
after_end

Why it doesn't work in the after()?


Solution

  • The test finishes too fast. You need to use the asynchronous version of after.

    after(function(done) {
        console.log("after");
        rmdir('tmp', function() {
            console.log("rmdir!");
            done();
        });
        console.log("after_end");
    });
    

    Which should output:

     after
     after_end
     rmdir!
    

    The reason it appears to work when you call it from before(), is because there are plenty of other things happening, so rmdir will get called, but later when node goes back to the event loop.