【问题标题】:mocha testing beforeEach inside a loop - asynchronous issue [duplicate]摩卡在循环内测试 beforeEach - 异步问题 [重复]
【发布时间】:2015-08-04 03:45:46
【问题描述】:

所以,我正在我的 node.js 应用程序上运行一些测试。

测试遍历我的所有模型并检查每个模型的公开 api。 it 调用仅检查公共模型,具体取决于模型的 public 属性。

在调用it 之前,我想在每次迭代中使用beforeEach 将一些测试数据传递给模型。不幸的是,由于异步调用(我猜),beforeEach 中的迭代器值保持不变。我猜循环甚至在beforeEach 之前执行。每个模型我有两个it 调用,导致每个模型调用beforeEach 两次。


更新

我想我必须展示我的整个用例,因为这比我在这里问的要复杂一些。 Cody 的解决方案似乎可行,但它仍然对我的用例没有帮助。这是因为我在循环中有一些条件,它们只对某些模型而不是全部运行测试。此外,还有两个 it 调用,这意味着循环的每次迭代都会调用两次 beforeEach。代码如下:

var models = {'Ate': {'property1': 'prop'}, 'Bat': {'property2': 'prop2'}, 'Cat': {'property3': 'prop3'}};
var modelConfigs = {'Ate': {'public': 'true'}, 'Bat': {'public': 'false'}, 'Cat': {'public': 'true'}};

describe('Given an array of model objects', function(){

    for(var key in modelConfigs) {

        var m = key;
        var modelConfig = modelConfigs[m];
        var model = models[m].definition;
        var modelPlural = models[m].settings.plural;

        if(modelConfig.public) { // Condition runs for only some models     
            beforeEach(function (done) {
               var test = this;
               var testKey = m;
               console.log(testKey); //Output is always Cat.
               done();
            });

            lt.describe.whenCalledRemotely('GET', '/api/' + modelPlural, function() {
                it('should have status code 200', function() { //First it call
                    assert.equal(this.res.statusCode, 200);
                });
                it('should be sorted DESC by date', function() { //Second it call
                    var modelRes = this.res.body;

                    expect(modelRes).to.be.instanceOf(Array);
                    expect(modelRes).to.have.length.below(11);
                    console.log(modelRes.length);

                    if(modelRes.length > 0) {
                        for(var i=1; i< modelRes.length; i++) {
                            expect(modelRes[i-1]['date']).to.be.at.least(modelRes[i]['date']);
                        }
                    }
                });
            });    
        }
    }
});

【问题讨论】:

  • 我们应该假设 app.models 看起来像 [{'a':'a'},{'b':'b'},{'c':'c'}] 还是像 {'a': 'a', 'b':'b', 'c':'c'}?因为{{'a':'a'},{'b':'b'},{'c':'c'}} 不是有效的javascript 对象。除此之外,您的 for 语句中有错字,应改为 for (var key in models) {
  • 我是匆忙打出来的,所以打错了。我猜代码只是代表性的。我现在已经进行了编辑:)
  • 没问题,当人们注意到这些小错别字时,最好纠正它们,因为这有助于人们回答问题。我在下面发布了一个“有效”的解决方案,但它肯定不是世界上最干净的解决方案。它基本上将 for 循环分解为 before/beforeEach 函数。
  • 你在你的 beforeEach 函数中做其他事情吗?因为,正如所写,您正在定义 x beforeEach 函数,其中 x 是模型的数量,这显然不是您想要做的,我会假设。我认为您仍然需要发布更多信息以获得更具体的帮助,但请查看上面链接的 Louis 问题和答案,它可能会有所帮助。
  • 确实是闭包的问题!谢谢路易斯。我用 forEach 来解决这个问题。现在一切正常:)

标签: javascript node.js asynchronous mocha.js loopbackjs


【解决方案1】:

以下代码有效,但我确信有更清洁的解决方案可用:

var models = {'a': 'a', 'b':'b', 'c':'c'}
var modelsArray = []
for(var key in models) {
  modelsArray.push(key)
}
describe("Given models", function () {
  var currModel, index, testKey, test
  before(function() {
    index = 0;
  })
  beforeEach(function() {
    test = this;
    testKey = modelsArray[index]
    currModel = models[testKey]
    index++
  })
  for(var i = 0; i < modelsArray.length; i++) {
    it("Does whatever you need to test", function() {
      console.log(testKey)
    })
  }
})

【讨论】:

  • 嘿科迪,请看看我的更新,也许这会让你更好地了解我的问题到底是什么。您的解决方案适用于我提出的问题,但我的用例有点复杂。已相应地编辑了问题。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-24
  • 2018-02-03
  • 1970-01-01
  • 2018-06-01
  • 2019-01-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多