Best way to test Javascript functions that use variables from closure?

So, the problem that I encountered is a function that uses a variable in closure and when testing it returns a reference to the variable in it. My code looks something like this:

var app = function() { var theString = ""; //Appends ztvars onto the url passed into the function var appendString = function(url) { if (theString.length === 0) { return url; } return url+theString; }; //Used for testing, returns the function appendPageVars this.returnFunctions = function() { return { appendString: appendString }; } } 

And the testing code using QUnit is as follows:

 var theApp = new app(); appFunctions = theApp.returnFunctions(); test('appendString()', function() { var theString = "TestString"; var theUrl = "http://www.test.com"; equals(appFunctions.appendString(testUrl), theUrl+theString, "Checking the string appended to the url"); //Fails }); 

The problem is that even when passing the function back to the test, the appendString function still contains a link to a string defined inside the application scope.

I managed to get around this problem by creating a function clone using eval, and not using it directly like this:

 var theApp = new app(); appFunctions = theApp.returnFunctions(); test('appendString()', function() { var theString = "TestString"; var theUrl = "http://www.test.com"; eval("var appendString = "+appFunctions.appendString.toString()); equals(appendString(testUrl), theUrl+theString, "Checking the string appended to the url"); //Passes }); 

However, I was always taught to avoid eval, and so I was wondering if there is a better way to do this? Am I missing something here, or is it how it should be done?

+4
source share
2 answers

So, as far as I can tell, the answer is to use Eval to recreate the function (as in my example). Although eval teaches to avoid in this case, this is apparently correct. Thanks for all your help!

0
source

What you need is an dependency injection when you provide the object to the layout.

 var App = function (theString) { theString = theString || ''; // optional argument var appendString = function (str) { return theString + str; }; this.returnFunctions = function () { return { appendString: appendString }; }; }; test('appendString()', function () { var app = new App('TestString'); var fns = app.returnFunctions(); equals(fns.appendString('test'), 'TestStringtest', ...); }); 
0
source

Source: https://habr.com/ru/post/1396108/


All Articles