Robin
Robin

Reputation: 529

Mocha JS: How to reference members from asynch before function in describe/it test functions

I'm trying to dynamically load settings asynchronously from config files before running a test suite. The test suite needs to take a config object to test, and create a server connection from it beforeEach test - then close the server connection afterEach test. I have the following code outline, but the test suite (nested describe) is always called before the setup (before) function has finished; which means that the testConfigs array is always empty. Is what I'm trying to do achievable, or will I have to fundamentally change the test?

describe('test server configs', function ()
{

    var testConfigs = [];

    before('get server configurations', function (done) {
        var conf = path.resolve('conf');
        fs.readdir(conf, function (err, files) {
                files.forEach(function (file) {
                    var config = require(path.join(conf, file));
                    testConfigs.push(config);
                });
            }

            console.dir(testConfigs); //prints the non-empty array
            done(err);
        });
    });

    describe('server test suite', function () {

        if (testConfigs.length == 0) {
            it('No server configurations to test!'); //0 tests passed, 1 pending
        }
        else {
            testConfigs.forEach(function (config) { //testConfigs is empty here
                var connection;

                beforeEach('connect to the server', function (done) {
                    connection = ServerConnection(config);
                    done();
                });

                it('should do something with the remote server', function (done) {
                    //test something with the 'connection' object
                    expect(connection.doSomething).withArgs('just a test', done).not.to.throwError();
                });

                afterEach('close connection', function (done) {
                    connection.close(done);
                });

            });
        }
    });

});

results:

      test server configs
[ [ 'local-config.json',
    { host: 'localhost',
      user: 'username',
      pass: 'password',
      path: '/' } ],
  [ 'foo.com-config.json',
    { host: 'foo.com',
      user: 'foo',
      pass: 'bar',
      path: '/boo/far' } ] ]
    server test suite
      - No server configurations to test!


  0 passing (25ms)
  1 pending

Upvotes: 0

Views: 337

Answers (1)

just-boris
just-boris

Reputation: 9746

You can add new tests when test run already has been started. If you want to dynamically generate test cases, you should do it before test start. You can use synchronous methods to read configs before tests

var testConfigs = []
var conf = path.resolve('conf');
var files = fs.readdirSync(conf);
files.forEach(function (file) {
    var config = require(path.join(conf, file));
    testConfigs.push(config);
});

describe('server test suite', function () {
   testConfigs.forEach(function (config) {
      //describe your dynamic test cases
   });
});

UPD 26.07.15

If you can't use synchronous function for some reasons, you can run mocha programmatically when you setup has done.

var Mocha = require('mocha');
var fs = require('fs');
var mocha = new Mocha({});

var testConfigs = global.testConfigs;
fs.readdir(conf, function (err, files) {
    files.forEach(function (file) {
        var config = require(path.join(conf, file));
        testConfigs.push(config);
    });
    mocha.run();
});

You have to pass the testConfigs via global scope, because mocha loads modules with test synchronously and this config must be ready untill the moment when mocha requires your tests.

Upvotes: 1

Related Questions