2012-02-13 4 views
4

私が抱えている問題は、クロージャーで変数を使用する関数を持っていることです。それをテストすると、変数の参照がスコープ内に返されます。私のコードは次のようになります。QUnitを使用してクロージャの変数を使用する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 }; 
    } 
} 

とテストコードは、次のようになります。

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機能を機能を渡しても、ということですappスコープ内で定義されたtheStringへの参照を保持します。

私はむしろ直接ので、同じようにそれを使用するよりもevalを使用して関数のクローンを作成することによってこの問題を回避するために管理してきました:私は常に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 
}); 

ので、私これを行う良い方法があるのだろうかと疑問に思っていましたか?私はここに何かを見逃しているのですか、それともこれはどうやってやろうとしていますか?

+1

これは構文エラーです。 'this.returnFunctions(){' –

+0

これは、JavaScriptの仕組みです。それは静的なスコープを持っています。関数を実行するときに動的スコープをシミュレートすることが可能かどうかはわかりません。 –

+0

@ imeVidas - 構文エラーが修正されました。だからこれを行うには良い方法はありません? – Tim

答えて

0

私の答えは、私の例によると、関数を再作成するためにEvalを使うことです。この場合、evalは避けるべきであると教えられていますが、それは正しいことです。誰もが助けてくれてありがとう!

0

オブジェクトにモックオブジェクトを提供するときに依存性注入が必要です。

+0

実際のコードでは、関数Appは50以上の異なる関数を持っています(appendStringだけでなく)。これは単純な例です。単体テストのために変更することもできません。 これは回避策ですが、元の問題を解決するわけではありません。つまり、関数を単体テストしても元の値が元のクロージャから参照されている場合です。 – Tim

関連する問題