blekione
blekione

Reputation: 10590

Mocking a global object when unit testing function with jasmine

I need to write tests for legacy JavaScript script which runs from node.js. It has a global object which is initialised in one function and then accessed from another. I mean script.js looks like:

var object;

function first() {
    object = Initialise.object();
    ...
}

function second() {
    object.doSomething();
    ...
}

I need to write a unit test for the second() function. We are using a jasmine test framework and I am struggling to create a mock (stub) for the object. It is because I don't know how can I access it from script-spec.js. I have tried

var script = require("../src/script.js");
var testObject = script.object;

but testObject is undefined.

My knowledge of JavaScript is limited which doesn't help me as well (I have Java background).

How can I test second() function? I understand that I might need to refactor/redesign script.js which I am OK with.

Upvotes: 1

Views: 1560

Answers (2)

Bryan Downing
Bryan Downing

Reputation: 15472

I would rewrite the code to be more functional:

function first() {
    return Initialise.object();
}

function second(object) {
    object.doSomething();
    ...
}

Then later when the code is used:

var object = first()
second(object)

Then mocking becomes pretty trivial, because you can control what gets passed as an argument to second in the test.

Check out Avoid Side Effects in the Clean Code Javascript repo for some more info about this.

Upvotes: 2

generalhenry
generalhenry

Reputation: 17319

It would be easier if it was a global variable, you could just do a global.object = mockObject. What it really is a module level variable, modules are really just functions. The only way to reassign object is from a function defined inside script.js such as

function injectMockObject (mockObject) {
  object = mockObject;
}

which you would need to add to script.js

Upvotes: 1

Related Questions