Mocha-未能循环通过在before()中初始化的数组

时间:2018-10-22 13:12:46

标签: node.js mocha

考虑此测试设置:

var expect = require('chai').expect;
var fs = require('fs');

describe('my test', function() {

    var dataArr;

    // get data
    before(function(done) {
        fs.readFile('myArray.json', 'utf8', function (err, data) {
            dataArr = JSON.parse(data);
            done();
        });
    });

    // test data
    dataArr.forEach(function(val, index) {
        it('Testing element no ' + (index+1), function(done) {
            expect(val).to.be.cool;
            done();
        });
    });

});

此测试返回错误Cannot read property 'forEach' of undefined,因为循环在before()之前执行。

我在使用嵌套it的SO上发现this approach,但这似乎是一种肮脏的解决方法(对mocha nested it进行搜索证明了这一点)。

对于这个不太常见的(?)问题,没有任何干净的解决方案吗?

3 个答案:

答案 0 :(得分:0)

我认为不存在任何更清洁的解决方案。

在您的示例中,在评估dataArr时未定义它,这意味着forEach成员尚不存在,因为dataArr当时还不是数组。它将在it()的回调函数范围内定义,因为it()回调函数是在“之前”回调之后调用的。

因此嵌套的“描述”解决方案行之有效,因为它可以固定评估顺序,以便在该点定义dataArr。

所以已经提到的解决方法是这样的:

var assert = require('assert');
var fs = require('fs');

describe('my test', function() {

    var dataArr;

    // get data
    before(function(done) {
        dataArr =  ["cool", "cool", "cool"]; // or fs.readFile or require
        done();
    });

    // test it

    it('test after data setup', function() {
        describe('the tests', function() {
            // now the dataArr is defined!
            dataArr().forEach(function(val, index) {
                it('Testing element no ' + (index+1), function(done) {
                    assert.equal(val, "cool");
                    done();
                });
            });
        }); 
    });
});

另一方面,如果您不更改dataArr,则可以在声明的位置立即评估它,例如:

var assert = require('assert');
var fs = require('fs');

describe('my test', function() {

    const dataArr = ["cool", "cool", "cool"]; // or dataArr = require('testfile.json');

    before(function(done) {

        done();
    });

    // test it

    // now the dataArr is defined!
    dataArr().forEach(function(val, index) {
        it('Testing element no ' + (index+1), function(done) {
            assert.equal(val, "cool");
            done();
        });
    });
});

答案 1 :(得分:0)

测试是同步定义的。是通过异步done调用而不是dataArr.forEach推迟的测试功能。

在这种情况下,异步readFile没有任何好处。这样会更简单:

before(function() {
    const data = fs.readFileSync('myArray.json', 'utf8');
    dataArr = JSON.parse(data);
});

根本不需要readFile。读取文件不是测试的一部分,应该执行一次。 Node.js本机支持导入JSON文件:

var expect = require('chai').expect;
var dataArr = require('./myArray.json');

答案 2 :(得分:0)

您正在从Mocha手中执行forEach方法,应该将所有逻辑移到it方法内

因此,如下更新代码:

it('Testing elements', function(done) {
    expect(dataArr).all.to.be.cool;
});