0

I have a working node script and am now trying to learn mocha/chai to add some unit tests.

//Module Code
var path = require('path');
var recursive = require('recursive-readdir');


function findData(folderPath) {
  recursive(folderPath, function (err, files) {
    return files;
  });
};

module.exports.findData = findData;

My mocha test code:

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

describe('checkData', function () {
  var findData = require('../custom_modules/findData').findData;
  var path;

  before (function () {
    path = '/Data'
  });

  it('should have 53 files in array', function () {
    expect(findData(path)).to.have.lengthOf(53);
  })

});

However, it always fails because the return seems to be undefined. So i stripped my module code back to test a return true and that worked.

So it must the the asynchronous nature of the recursive module so I then tried add in callbacks to my module code:

var path = require('path');
var recursive = require('recursive-readdir');


function findData(folderPath, cb) {
  recursive(folderPath, function (err, files) {
    cb(null, files);
  });
};

module.exports.findData = findData;

But that didn't work either.

The weird thing is if I run node index.js i get the list of files.

Can anyone explain to me how this code can work normally but when I try to use mocha/chai to test I get undefined?

Thanks

EDITED:

So based on what @Louis said in the comments I have added a callback to the function.

describe('checkData', function () {
  var findData = require('../custom_modules/findData').findData;
  var path;
  var files;

  before (function () {
    path = '/Users/tjmartin/Documents/OSData/OpenNames/Data'
  });

  it('should have 53 files in array', function () {
    expect(findData(path, function(results) {
        files = results;
      })).to.have.lengthOf(53);
  })
});

But this still returns an undefined.

tjmgis
  • 1,589
  • 4
  • 23
  • 42
  • You've shown your original implementation, your original testing code, and your new implementation, but you should also show the new testing code you are using now. Ideally, your question should contain a [mcve]. – Louis May 04 '16 at 14:24
  • @Louis not sure I understand your comment. I have said that I attempted to change my module code to use callbacks but that didn't work. I have not changed my testing code. – tjmgis May 04 '16 at 14:26
  • Well, then why should it work *at all* if you did not modify your testing code? In your test code you are calling `findData(path)` without passing a callback but your new `findData` requires a callback. – Louis May 04 '16 at 14:38
  • @Louise I have tried to add a callback to the function in my expect test but it still returns undefined. – tjmgis May 04 '16 at 15:03
  • Possible duplicate of [How do I return the response from an asynchronous call?](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Louis May 04 '16 at 15:16

1 Answers1

1

First up, I would log the err result in your findData implementation. Even if only during development, so you can easily see if any errors are reported (you may be doing this already, just wanted to mention it).

As you have spotted, one of the main causes of problems for you is that the callback is asynchronous. So you can't simply return it from your findData method as in your original example.

Next, I wouldn't hard-code the path as you have in the before function. Instead use a local path, so that the test can be run as part of your CI (if you ever have one) or even so you can grab it on another machine and have it work there.

before(function() {
    path = './tests/TestData';
});

In your revised example, although you are using a callback you are testing the return result still. You need to alter your test to use the result of the callback.

it('should have 53 files in array', function(done) {
    findData(path, function(results) {
        expect(results).to.have.lengthOf(53);
        done();
    });
});
nfactorial
  • 187
  • 4
  • many thanks. This works brilliantly. I was looking for callbacks on my chai code rather than the mocha. – tjmgis May 04 '16 at 15:49