用generator编写异步JavaScript测试

廖雪峰 / 编程 / ... / Reads: 2921

Mocha是JavaScript/Nodejs的一个非常优秀的测试框架,本身就支持同步和异步测试,不过,异步测试由于要显式调用done(),容易造成异步代码callback嵌套过深,不利于看懂和维护测试代码:

it('async test', function(done) {
    doSomethingA(function (err, r1) {
        // check...
        doSomethingB(function (err, r2) {
            // check...
            done();
        });
    });
});

于是这位老兄想到用ES6的generator来测试:Yield to the test: using Mocha with ES6 generators

如果用generator编写测试代码,就可以写成:

it('async test', function*() {
    var r1 = yield doSomethingA();
    // check...
    var r2 = yield doSomethingB();
    // check...
});

这么写当然比较爽了,可惜Mocha的开发人员还不打算引入co来支持generator,所以,测试代码还得改成:

it('async test', function() {
    return co(function*() {
        var r1 = yield doSomethingA();
        // check...
        var r2 = yield doSomethingB();
        // check...
    });
});

每个TestCase都要多写几行完全一样的代码,自然不爽。于是这位老兄改写了mocha.Runnable.prototype.run

mocha.Runnable.prototype.run = function(fn) {
    ...
}

不得不说,这位老兄想法挺好,但是改错了地方,最新版的Mocha 2.1.0代码和他改的版本已经有很大不同了,要改也应该改Runnable的构造函数,这样改动最小,也最简单。

先把co源码下载一份,命名为co.js,然后修改:

// 新加:
var co = require('./co');

function isGeneratorFunction(obj) {
  var constructor = obj.constructor;
  return constructor && 'GeneratorFunction' == constructor.name;
} // END

function Runnable(title, fn) {
  // 新加:
  if (isGeneratorFunction(fn)) {
    var f = fn;
    fn = function () {
      return co(f);
    };
  } // END
  ...
}

isGeneratorFunction是从co的源码复制出来的。改完了,就可以直接运行generator的TestCase了。

Comments

Make a comment

Author: 廖雪峰

Publish at: ...

关于作者

关注公众号不定期领红包:

关注微博获取实时动态: