不能在async-promise函数中使用Jasmine的'It'块

时间:2016-10-21 07:46:43

标签: node.js promise protractor jasmine2.0 exceljs

我在循环中使用IT块时遇到问题。循环基本上来自返回的Promise,一个 exceljs 模块,用于从excel文件中读取数据。

这是承诺函数。

var excelJs = require('exceljs');
var Excel = browser.params.Excel;

this.createProfile = function() {
        var arr = [];
        return new Promise(function(fulfill, reject){
        var workbook = new excelJs.Workbook();

        workbook.xlsx.readFile(Excel.filePath).then(function(){    
            worksheet = workbook.getWorksheet(1);
            worksheet.eachRow({includeEmpty: true}, function(row, rowNumber)
                try {
                    if (rowNumber != 1) {
                        arr.push(row.values);
                        fulfill(arr);
                    }
                } catch(ex){reject(ex);}
              }, reject);
            });
        });
};

以下是我在spec文件中调用的方法。

describe('Bulk Purchase', function(){

        var cp = createProfile();
        cp.then(function(data){
            for (var i in data){
                it('Automate School Supplies Purchase', function(done){
                    console.log('Ballpen: ' + data[i][1]);
                    console.log('Notebook: ' + data[i][2]); //etc
                    done();
                });
            }
        })
    });

如果我从代码中删除 IT 块,则规范将显示预期值。有人可以告诉我为什么一个简单的 IT 阻止一个承诺不起作用?任何帮助将不胜感激,谢谢:)

我有一个解决方法,如果我将Excel转换为JSON,并且需要json文件并执行forEach,那么我可以轻松地进行数据驱动的自动化测试。但我宁愿不从其他源文件移动来实现我原来的方法。

// where I used xlsx-to-json npm to convert my excel to json
var jsonData = require('path to converted excel to json file');

jsonData.forEach(function(data){
   it('Automate School Supplies Purchase', function(){
      console.log(data.Ballpen);
      console.log(data.Notebook); //etc
   })
});

3 个答案:

答案 0 :(得分:0)

所有描述和它的陈述需要是同步的。 Mocha / Jasmine在脚本开始时读取他们的信息。你所有的异步内容都必须在它/ beforeEach / afterEach等的cb函数中。

您无法基于异步数据创建测试用例。唯一的解决方案是为所有情况提供一个大的声明:

describe('Bulk Purchase', function() {
  it('Automate School Supplies Purchase', function(done) {
    var cp = createProfile();
    cp.then(function(data) {
      for (var i in data) {
        console.log('Ballpen: ' + data[i][1]);
        console.log('Notebook: ' + data[i][2]); //etc
      };
      done();
    });
  });
});

答案 1 :(得分:0)

您可以使用" jasmine-data-provider"进行数据驱动测试而无需任何for循环。

Data-Driven Testing in Protractor

答案 2 :(得分:-1)

找到最好的一个,Node.js async to sync

deasync包为我提供了解决方案。 更新:对于那些想要我如何使用deasync进行操作的人。

/*** My function ***/
this.createProfile = function() {

    var arr = []; 
    // pseudo code goes here cont..
    arr.push = row.values

    // Deasync goes here
    while(arr === "undefined") {
      require('deasync').runLoopOnce();
    }
    return arr;
};

现在在我的规范测试中使用它。它做了我期待的事情。

 describe('Bulk Purchase', function(){

    var cp = createProfile(); // cp value is now a SYNC one
    cp.forEach(function(data, index){
       for (var i in data) {
         it('School Supplies purchase', function(done){
            console.log('Ballpen: ' + data[i][0];
            console.log('Books: ' + data[i][1];
         })
       }

    })
});