我正在使用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
});
});
似乎冗长且不太可读。有没有更好的方法来编写这段代码?
答案 0 :(得分:0)
就摩卡而言,你发现作品的两种方式就是它。
Mocha分两个阶段进行:测试发现和测试执行。 (我认为文档没有说明这一点。)在测试发现期间,传递给describe
和context
的回调被Mocha称为立即。在测试执行期间调用before
,beforeEach
挂钩。 (请参阅此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()
的失败对任何其他测试都没有任何影响。