摩卡异步执行顺序

时间:2016-01-06 21:57:41

标签: javascript unit-testing asynchronous mocha

我正在使用Mocha进行AMD(requirejs)模块的js单元测试。由于模块需要由requirejs加载,因此测试是异步的:

'use strict';

var chai = require('chai');
var should = chai.should();
var requirejs = require('requirejs');
requirejs.config({
    baseUrl: '../../',
    paths: {
        PieWidget: 'tools/scheduler/PieWidget'
    }
});

describe('PieWidget tests', function() {
    var PieWidget, pw1, pw2;
    before('Set up the PieWidget module', function(done) {
        requirejs(['PieWidget'], function(_) {
            PieWidget = _;
            done(); // tell Mocha we are now ready to run the tests
        });
    });

    // tests here
};

为了便于阅读和简洁,我想说:

context('when the constructor is called', function() {
    pw1 = new PieWidget();
    it('should create a valid PieWidget', function() {
        pw1.should.exist;
        //todo check validity
    });
});

但是Mocha不按顺序运行这些行。为了满足摩卡,我必须:

context('when the constructor is called', function() {
    it('should create a valid PieWidget', function() {
        pw1 = new PieWidget();
        pw1.should.exist;
        //todo check validity
    });
});

在我看来,描述与逻辑之间存在不匹配,或者:

context('when the constructor is called', function() {
    before(function() {
        pw1 = new PieWidget();
    });
    it('should create a valid PieWidget', function() {
        pw1.should.exist;
        //todo check validity
    });
});

似乎冗长且不太可读。有没有更好的方法来编写这段代码?

1 个答案:

答案 0 :(得分:0)

就摩卡而言,你发现作品的两种方式就是它。

Mocha分两个阶段进行:测试发现和测试执行。 (我认为文档没有说明这一点。)在测试发现期间,传递给describecontext的回调被Mocha称为立即。在测试执行期间调用beforebeforeEach挂钩。 (请参阅此answer中输出数字的console.log调用示例以查看此操作中的顺序。)在测试发现期间,您不能执行任何依赖于测试执行期间执行的代码的操作。这是违反您的代码的原则:new PieWidget()before挂钩之前执行

现在,我认为这是编写测试的正确方法:

context('the constructor', function() {
    it('should create a valid PieWidget', function() {
        var pw1 = new PieWidget();
        pw1.should.exist;
        //todo check validity
    });
});

为什么呢?您的初始尝试不起作用,因为Mocha不允许它,但假设它确实如此。并假设你的构造函数崩溃了。 Mocha对这次失败有什么看法?我可以告诉你摩卡会做什么。它根本不会执行任何测试。如果您碰巧测试了套件中的另一个对象(不受PieWidget错误的影响),那么这些测试也不会运行。摩卡会马上放弃。

如何将创建放在before挂钩中,您发现它很有效。这仍然不是一个好主意。最终的结果会有所不同,但它之所以糟糕的原因基本相同:Mocha不会运行尽可能多的测试。如果你的PieWidget有问题,那么钩子就会崩溃。 Mocha将钩子中的崩溃解释为测试套件本身错误并将中止执行的标志。在崩溃之前执行的任何测试都没有问题,但是在崩溃之后执行的任何测试都不会被执行。

按照上面显示的方式执行此操作可确保在运行测试套件时,Mocha将运行最多数量的测试。在您的测试中new PieWidget()的失败对任何其他测试都没有任何影响。