如何使用mocha分解常见的before()调用?

时间:2015-03-28 00:43:28

标签: node.js mocha

我的mocha测试中有很多重复:

describe("Some test", function() {
    before(helpers.testPrepare);
    beforeEach(helpers.freshDB);

    it("should foo", function(done) {
        //...
        done();
    });

    after(helpers.teardownServer);
});

describe("Another test", function() {
    before(helpers.testPrepare);
    beforeEach(helpers.freshDB);

    it("should bar", function(done) {
        //...
        done();
    });

    after(helpers.teardownServer);
});

如果我忘记致电beforeEach并且重构很痛苦,这可能会导致问题。我想定义一个describe来确保我总是打电话给我的设置和拆解,所以我可以写一下:

我想把它写成:

var describe = require('./helpers').describe;

describe("Some test", function() {
    it("should foo", function(done) {
        //...
        done();
    });
});

我怎么能这样做,因为mocha将describe定义为全局?我如何确保以正确的顺序执行所有操作?

3 个答案:

答案 0 :(得分:6)

我会创建一个包含此内容的helpers.js文件:

function beforeEachExample() { console.log("before each"); }

function beforeExample() { console.log("before"); }

function afterExample() { console.log("after"); }

function makeSuite(desc, cb) {
    describe(desc, function () {
        before(beforeExample);
        beforeEach(beforeEachExample);

        cb();

        after(afterExample);
    });
}

exports.makeSuite = makeSuite;

然后我可以test/something.js

var makeSuite = require("../helpers").makeSuite;

makeSuite("something", function () {
    it("one", function () {});
    it("two", function () {});
});

test/somethingelse.js

var makeSuite = require("../helpers").makeSuite;

makeSuite("something else", function () {
    it("one", function () {});
    it("two", function () {});
});

运行上面的设置会产生:

$ mocha

  something
before
before each
    ✓ one 
before each
    ✓ two 
after

  something else
before
before each
    ✓ one 
before each
    ✓ two 
after

  4 passing (5ms)

答案 1 :(得分:1)

您可以在彼此之间组合describe块。所以现在你可以做到。 。

describe('Database Tests', function () {
  before(helpers.testPrepare);
  beforeEach(helpers.freshDB);

  describe('Some test', function () {
   it('should foo', function (done) {
    done();
   });
  });

  describe('Another test', function () {
   it('should bar', function (done) {
     done();
   });
  });
});

编辑:关于您的评论,您可以尝试创建模块。

harness.js
module.exports.beforeHooks = function () {
 before(hlepers.testPrepare);
 beforeEach(helpers.freshDB);
}

然后这样做......

var harness = require('./harness.js');
describe('Database Tests', function () {
  harness.beforeHooks();

它可能无法正常工作,因为范围界面全部搞砸了,但如果是这样的话,您可以在beforeHooks函数中传递这些函数。

module.exports.beforeHooks(before, beforeEach)

并像以前一样调用它,但是将这些函数作为对象传递给它。

harness.beforeHooks(before, beforeEach);

答案 2 :(得分:0)

如果你想在测试套件中的 EVERY TEST 之前运行同一组before / beforeEach挂钩,那么你可以在任何describe之外的全局级别声明这些挂钩块。

// test/support/init.js
before(helpers.testPrepare);
beforeEach(helpers.freshDB);
after(helpers.teardownServer);

// test/mocha.opts
-r ./test/support/init.js

// test/some.test.js
describe("Some test", function() {
  it("should foo", function(done) {
    //...
    done();
  });
});

// test/another.test.js
describe("Another test", function() {
  it("should bar", function(done) {
    //...
    done();
  });
});

如果您只想在选定的测试子集中调用设置,那么您可以按如下方式实现辅助方法:

helpers.describe = function decoratedDescribe(name, fn) {
  global.describe(name, function() {
    before(helpers.testPrepare);
    beforeEach(helpers.freshDB);
    after(helpers.teardownServer);

    fn();
  });
};

// test/some.test.js
var describe = require('./helpers').describe;
describe("Some test", function() {
  it("should foo", function(done) {
    //...
    done();
  });
});

请记住,所有Node.js代码都被require()加载时包含在函数中,因此var describe会创建一个局部变量,遮蔽Mocha提供的全局变量。

这个解决方案的明显缺点是嵌套的describe块会再次添加所有钩子,这几乎肯定不是你想要的。在这种情况下,我建议您保留Mocha提供的原始describe,并以不同的名称存储您的自定义实现。

// test/some.test.js
var describeWithSetup = require('./helpers').describe;
describeWithSetup("Some test", function() {
  describe("some context", function() {
    it("should foo", function(done) {
      //...
      done();
    });
  });
});