0

The below files are within a project created with the generator-webapp generator for Yeoman. My script is working in the browser and returns the information from the JSON file but does not work in the test most of the time. The test succeeds sometimes which means the test hits a hiccup long enough to allow the getJSON to return the data in time. In my search, I found various resources, here are two sources that sounded like they should be solving my issue: a stackoverflow question and a blog.

They both involve passing the done parameter to the it function and then calling done(); after executing the test. At least, that is my understanding but it still isn't working. I feel I am missing something really obvious.

Here is app/scripts/source-data.js.

var source = (function() {
    var sourceData = null;

    _loadData();

    function _loadData(done) {
        $.getJSON("app/data/source.json", function(data) {
            sourceData = data;
        });
    }

    function getData() {
        return sourceData;
    }

    return {
        getData: getData
    };
})();

Here is test/spec/source-data.js.

(function() {
    describe("Source Data", function() {
        describe("Data for External Modules", function() {
            it("returns the source data from a file", function(done){
                expect(source.getData().spec[0].name).to.equal("Spec");
                done();
            });
        });
    });
})();

I tried altering where done() is called as my understanding was that done() tells Mocha to go ahead with the rest of the test after the getJSON is done. However, at this point, this was just trial and error as I found I had no real understanding.

...
var data = source.getData();
done();
expect(data.spec[0].name).to.equal("Spec");
...

Following the above, I tried setTimeout in the main script but that still didn't work! Even if it did, I don't think I should use setTimeout in this situation, but properly wait for the resolution of getJSON.

Community
  • 1
  • 1
KrimCard
  • 213
  • 2
  • 5
  • 12

1 Answers1

0

You should use callback. For example:

var source = (function() {
  var sourceData;

  function getData(done) {
    if(sourceData){
      done(sourceData);
    } else {
      $.getJSON("app/data/source.json", function(data) {
        sourceData = data;
        done(data);
      });
    }
  }
  return {
    getData: getData
  };
})();

and test will be like this

(function() {
  describe("Source Data", function() {
    describe("Data for External Modules", function() {
      it("returns the source data from a file", function(done){
        source.getData(function(sourceData){
          expect(sourceData.spec[0].name).to.equal("Spec");
          done();
        });
      });
    });
  });
})();
Rudolf Manusachi
  • 2,311
  • 2
  • 19
  • 25
  • I came up with a solution from an above comment but I found your solution to be more concise and I went with it. Thanks. – KrimCard Dec 09 '15 at 03:36