3

I have client-side JavaScript that does not interact with the DOM or the web-browser in any way. I would like to unit-test the functionality of this code (which is just a fancy database/buffer) in Travis-CI without starting up a web-browser. Command-line JavaScript made me think I need node.js. I looked through various unit-testing libraries and decided on Mocha for its simplicity, however testing a browser-based module/class seems to be excessively difficult with a node.js based library.

Specifically, I want to test this (simplified) browser JavaScript valid code:

// I need this NameSpace to organise my code and isolate from other code
var Nengo = {};

Nengo.DataStore = function(dims) {
    this.times = [];
    this.data = [];
    for (var i=0; i < dims; i++) {
        this.data.push([]);
    }
}

Nengo.DataStore.prototype.push = function(row) {
    this.times.push(row[0]);
    for(var i = 0; i < this.data.length; i++){
        this.data[i].push(row[i+1]);
    }
}

When I try to test in Node.js, I can't import the idea of the Nengo namespace properly. This test can't even run:

// get the datastore code from the folder below
require("../simple_data")
var assert = require("assert")

describe("DataStore", function() {
    var data_store = new Nengo.DataStore(2);

    it("accepts data", function() {
        data_store.push([0.0, 1.1, 1.2])
        assert.deepEqual(data_store.data, [[1.1], [1.2]])
    });
});

It fails with the following error:

/home/saubin/javascript_test/test/simple_test.js:5
    var data_store = new Nengo.DataStore(2);
                     ^
ReferenceError: Nengo is not defined
    at Suite.<anonymous> (/home/saubin/javascript_test/test/simple_test.js:5:22)
    at context.describe.context.context (/usr/local/lib/node_modules/mocha/lib/interfaces/bdd.js:49:10)
    at Object.<anonymous> (/home/saubin/javascript_test/test/simple_test.js:4:1)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.require (module.js:364:17)
    at require (module.js:380:17)
    at /usr/local/lib/node_modules/mocha/lib/mocha.js:192:27
    at Array.forEach (native)
    at Mocha.loadFiles (/usr/local/lib/node_modules/mocha/lib/mocha.js:189:14)
    at Mocha.run (/usr/local/lib/node_modules/mocha/lib/mocha.js:422:31)
    at Object.<anonymous> (/usr/local/lib/node_modules/mocha/bin/_mocha:398:16)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:935:3

One way I have thought of solving this is abandoning node and outputting the test results to the DOM of a headless browser and getting the results, but this seems like a lot of excessive overhead. Can I change the structure of my code to be compatible with Node.js? Is there some other solution that I'm not seeing due to lack of knowledge in the area?

10
  • Does Nengo exist as a node module? How are you loading it? Commented Aug 15, 2015 at 0:37
  • It's not a node module, because it only runs in the client-side browser and from what I understand for it to be an actual node module I would have to be running it on the server side. I'm loading it as shown in the code above, mostly because I don't know how else to load it. Commented Aug 15, 2015 at 0:38
  • @DaveNewton forgot to mention you in my last comment Commented Aug 15, 2015 at 0:48
  • So the library only runs on the client side, and node only runs on the server side... Send like this wouldn't work very well then, no? Commented Aug 15, 2015 at 0:49
  • @DaveNewton yeah, I'm realising that Node.js != JavaScript. However, the unit testing frameworks for them seem to be the same, so this is confusing me. Can I test client-side JavaScript code in the command-line or do I have to use a browser? Commented Aug 15, 2015 at 0:51

2 Answers 2

1

You can make your code "node.js-aware" so it puts global definitions into the actual global context while still remaining completely compatible with the browser environment:

if (typeof window !== "undefined") {
    // in browser, define global to be an alias for window
    // so global can be used to refer to the global namespace in
    // both the browser and node.js
    var global = window;
}

global.Nengo = {};

(function() {
    var Nengo = global.Nengo;

    Nengo.DataStore = function(dims) {
        this.times = [];
        this.data = [];
        for (var i=0; i < dims; i++) {
            this.data.push([]);
        }
    }

    Nengo.DataStore.prototype.push = function(row) {
        this.times.push(row[0]);
        this.data.push(row.slice(1));
    }
})();

Then, just remember that ANY global definitions, must be explicitly assigned to the global namespace. In node.js, this will assign them to the actual global namespace in node.js. In the browser, this will assign them to the window object which is the global namespace in the browser.

Sign up to request clarification or add additional context in comments.

2 Comments

Any particular reason you added a closure to my code?
@Seanny123 - Just to save some typing so I could define a local variable named Nengo that could be used like you were using it before. If you want to type out global.Nengo.Datastore = function() {...} for each of your method definitions, you don't need the closure.
0

Although, @jfrien00's answer is technically correct, I came up with another answer later.

First, I needed to refactor my JavaScript code to declare my namespace outside of the DataStore file. Then I declare the Nengo global variable as jfriend00 describes global.Nengo = {};, but only in my Mocha test file.

This way, when I run in my web browser and my unit tests, my code is tested as expected.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.