2012-02-13 43 views
4

所以我遇到的問題是我有一個函數,它在閉包中使用一個變量,當它測試它時,它返回一個對它的作用域中的變量的引用。我的代碼看起來類似於以下內容:測試使用閉包變量的Javascript函數的最佳方法?

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功能仍持有對應用程序範圍內定義的theString的引用。

我已經設法通過使用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等我想知道有沒有更好的方法來做到這一點?我在這裏錯過了什麼,或者這是應該如何完成的?

+1

這是一個語法錯誤:'this.returnFunctions(){' – 2012-02-13 03:17:24

+0

好吧,這就是JavaScript的工作原理。它具有靜態範圍。我不確定在執行函數時可以模擬動態範圍... – 2012-02-13 03:20:18

+0

@ŠimeVidas - 感謝語法錯誤已得到解決。所以沒有更好的方法來做到這一點? – Tim 2012-02-13 03:28:32

回答

0

因此,據我所知,答案是使用Eval重新創建函數(按照我的示例)。雖然eval在這種情況下被教導要避免,但似乎是正確的做法。謝謝大家的幫助!

0

當您爲對象提供模擬對象時,您需要的是依賴注入。

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

在實際的代碼中,App的功能超過了50個不同的功能(不僅僅是appendString)這只是一個簡單的例子。它也不能爲了單元測試而改變。 儘管這是一種解決方法,但它並不能解決原始問題,即當單元測試函數仍然從其原始閉包中引用原始值時。 – Tim 2012-02-22 22:37:30

相關問題