嵌套for Node.js中的循环以及Mocha测试框架

时间:2013-10-08 23:05:02

标签: javascript node.js testing asynchronous mocha

我正处于测试的某个阶段,我需要一个嵌套的for循环,但是我迷失了整个Async方面的东西。基本上现在发生的是我想迭代一个数组,并逐个使用值并记录输出。目前发生的事情是记录的唯一输出是我想要使用的最后一个值。这很难解释,所以我将演示我的代码。

// For the sake of it, all these values are strings
var arr1 = [ [1, 2, 3, 4], [2, 3, 4, 1], [3, 4, 2, 1], [4, 1, 2, 3] ];
var arr2 = [ [a, b, c, d], [b, c, d, a], [c, d, a, b], [d, a, b, c] ];

for(var i = 0; i < arr1.length; i++){
    describe("Test", function(){
        it("Does something", function(done){
            for(var x = 0; x < arr2.length; x++){
                it("Does something else", function(done){
                    // Do stuff with arr1[i], arr2[x] etc.
                    testFunc(arr1[i], arr2[x], function(returnValue){
                        assert.strictEqual(returnValue, true, "Passed!");
                        done();
                    }
                });
            }
        });
    });
}

现在,我无法填写代码实际执行的操作(隐私原因),但如果有人可以指出我可以使用这种方式(意味着循环等待来自testFunc()的回调每次)。

如果我们说testFunc()如下:

function testFunc(arr1var, arr2var, callback){
    console.log(arr1var + " and " + arr2var); 
}

当我运行它时,我看到的是传递给控制台的最终值('3和c')。

我一直在寻找这个但是因为人们的例子对他们的代码如此具体,所以尝试和适应它会让人感到困惑。我查看了Node.js Async模块,但也没有走得太远。

如果有人可以一步一步地跟我说话,或者按照我想要的方式重写上述内容,我会很感激。

另外,在我的实际代码中,我的数组在顶部是不同的大小 - 如果导致差异。

由于有几个人指出了这一点,我只想补充说,如果有人有更好的方法,我完全愿意接受建议。我将运行大约40个测试,并将其减少到10-15行代码,而不是200个单独调用,所以无论人们认为最好,请随时告诉我。

2 个答案:

答案 0 :(得分:3)

我的示例中没有看到任何代码味道。您只需使用async.each而不是for循环。另外,我不明白为什么你需要两个it语句。我会做一些像:

var async = require('async');
var expect = require('expect.js');
var _ = require('lodash');
var arr1 = [ [1, 2, 3, 4], [2, 3, 4, 1], [3, 4, 2, 1], [4, 1, 2, 3] ];
var arr2 = [ [1, 2, 3, 4], [2, 3, 4, 1], [3, 4, 2, 1], [4, 2, 2, 3] ];

describe('Array tests', function() {
  async.each(arr1, function(arr1Element, callback) {
    async.each(arr2, function(arr2Element, callback2) {
      it('Tests array elements', function(done) {
        expect(_.difference(arr1Element, arr2Element)).to.be.empty();
        done();
      });
      callback2();
    });
    callback();
  });
});

答案 1 :(得分:2)

问题是执行的第一个异步测试检查将调用done()并告诉mocha整个测试已经完成。您需要使用代码来完成done()调用,该代码计算已完成的测试数量,然后在最后一次完成后调用完成。

for(var i = 0; i < arr1.length; i++){
    describe("Test", function(){
        it("Does something", function(done){
            var remaining = arr2.length;
            for(var x = 0; x < arr2.length; x++){
                it("Does something else", function(done){
                    // Do stuff with arr1[i], arr2[x] etc.
                    testFunc(arr1[i], arr2[x], function(returnValue){
                        assert.strictEqual(returnValue, true, "Passed!");
                        remaining--;
                        if (remaining === 0) {
                            done();
                        }
                    }
                });
            }
        });
    });
}

那就是说,我不知道mocha是否支持多个同时的it()调用。您可能需要在其中移动两个循环()。

我觉得你在不同的点上有for循环而不是彼此相邻,这似乎很奇怪,但这可能只是你正在测试的结果。

更好的方法是切换到使用promises而不是异步回调,因为promises可以很容易地聚合,也就是说,当一个集合中的所有promise都完成后,它很容易调用函数。