Search code examples
node.jsmocha.jsmetalsmith

Testing metalsmith plugin that should throw an error using mocha


I'm writing a metalsmith plugin and its associated test suite with mocha.

The plugin should throw an exception if it lacks configuration:

function plugin(config) {
   ...
   return function(files, metalsmith, done) {
      ...
      done(new Error("config error"));
   }
}

and I try to test it with mocha this way:

describe('my plugin', function() {
it('should throw an exception', function(done) {
    var metalsmith = Metalsmith('test/fixtures/basic');
    metalsmith
        .use(myplugin({
            someconfig: {

        }))
        .build(function(err,files) {
            assert(err);
            done();
        });
  });
});

When I run the test I have this result:

my plugin
    ✓ should throw an exception 
    1) should throw an exception


  1 passing (31ms)
  1 failing

  1) my plugin should throw an exception:
     Error: done() called multiple times

So it seems the test is ok but somehow is run another time, failing this time...


Solution

  • The problem was that the error was throwed inside a foreach loop, causing done() to be called multiple times:

    Object.keys(files).forEach(function (file) {
    ...
    done(new Error("config error"));
    ...
    }
    

    Adding a simple return does not work because you can't return from a foreach loop.

    So using a simple for loop instead of the foreach, returning on the first error:

    for (var file in files) {
    ...
    return done(new Error("config error"));
    ...
    }