Лучший способ проверить функции Javascript, которые используют переменные из замыкания? - PullRequest
4 голосов
/ 13 февраля 2012

Итак, у меня проблема в том, что у меня есть функция, которая использует переменную в замыкании, и при тестировании она возвращает ссылку на переменную в своей области видимости. Мой код выглядит примерно так:

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 };
    }
}

И тестовый код с использованием QUnit выглядит следующим образом:

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
});

Проблема в том, что даже при передаче функции обратно в тест функция appendString все еще содержит ссылку на строку, определенную внутри области приложения.

Мне удалось обойти эту проблему, создав клон функции с помощью eval, а не используя его напрямую, вот так:

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
});

Однако меня всегда учили избегать eval, и мне было интересно, есть ли лучший способ сделать это? Я что-то здесь упускаю, или это как это должно быть сделано?

Ответы [ 2 ]

0 голосов
/ 23 февраля 2012

Итак, насколько я могу судить, ответ - использовать Eval для воссоздания функции (согласно моему примеру). Хотя eval учат избегать в этом случае, кажется, что это правильно. Спасибо за вашу помощь всем!

0 голосов
/ 13 февраля 2012

Что вам нужно, это внедрение зависимостей, когда вы предоставляете объекту фиктивный объект.

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', ...);
});
...