0

So, I'm running some tests on my node.js app.

The test iterates through all my models and checks each model's exposed api. The it calls check only the public models, depending on the model's public property.

Before the it calls are made, I want to pass some test data to the models using beforeEach at each iteration. Unfortunately, due to asynchronous calls (I'm guessing), the the iterator value in beforeEach remains the same. I'm guessing the loop is executed even before beforeEach. I have two it calls per model resulting in beforeEach being called twice per model.


UPDATE

I guess I'll have to show my entire use case cause this is a little more complicated than what I've asked here. Cody's solution seems possible, but it still doesn't help my use case. This is because I have a few conditions in the loop which runs the test only for certain models and not all. Also, there are two it calls, meaning beforeEach is called twice for every iteration of the loop. Here's the code:

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']);
                        }
                    }
                });
            });    
        }
    }
});
KaushikTD
  • 257
  • 3
  • 17
  • Are we supposed to assume app.models looks like `[{'a':'a'},{'b':'b'},{'c':'c'}]` or like `{'a': 'a', 'b':'b', 'c':'c'}`? Because `{{'a':'a'},{'b':'b'},{'c':'c'}}` is not a valid javascript object. Beyond that, your for statement has a typo in it, should read `for (var key in models) {` instead. – Cody Haines May 22 '15 at 08:10
  • I typed that out in a hurry, so made some typos. I guess the code is just representational. I've made edits now :) – KaushikTD May 22 '15 at 08:39
  • No problem, it's just always best to correct minor typos like that when they get noticed as it helps people answer the question. I've posted a 'working' solution below, but it's certainly not the cleanest solution in the world. It basically breaks up the for loop into the before/beforeEach functions. – Cody Haines May 22 '15 at 08:45
  • Are you doing other things in your beforeEach function here? Because, as written, you're defining x `beforeEach` functions, where x is the number of models, and that's obviously not what you want to be doing I would assume. I think you still need to post more information to get more specific help, but take a look at the question and answers Louis linked above, it might help. – Cody Haines May 22 '15 at 11:00
  • It was indeed an issue with closures! Thanks Louis. I used forEach to fix the problem. Everything's working fine now :) – KaushikTD May 22 '15 at 11:06

1 Answers1

0

The following code works, though I'm sure there's a cleaner solution available:

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)
    })
  }
})
Cody Haines
  • 1,157
  • 10
  • 16
  • Hey Cody, please take a look at my update, maybe that'll give you better insight into what my problem actually is. Your solution works for the question I had asked, but my use case is a little more complicated. Have edited the question accordingly. Thanks! – KaushikTD May 22 '15 at 10:23