2009-04-04 17 views
16

Javascriptでモジュールパターンを使用して、私のパブリックインターフェイスとプライベート実装を分離しています。私がやっていることを単純化するために、私のコードはチャートを生成します。JavaScriptのプライベート関数をテストする

var Graph = function() { 
    var private_data; 
    function draw_legend() { ... } 
    function draw_plot() { ... } 
    function helper_func() { ... } 
    ... 

    return { 
    add_data: function(data) { 
     private_data = data; 
    }, 
    draw: function() { 
     draw_legend() 
     draw_plot() 
    } 
    } 
} 

一部の人々は唯一の理にかなって、あなたのクラスのパブリックインターフェイスを、テストを提唱、私は思います:チャートは、複数の部品(車軸、ラベル、プロット、伝説など)で構成されて私のコードは次のようになりますいくつかのテストでコンポーネントのそれぞれを個別にテストするのが本当に好きです。私がdraw_legend()関数を使いこなせば、私はそのテストを失敗させたいと思います。public draw()関数のテストではありません。私は間違ったトラックにいますか?

私は、レジェンドクラスを作るなど、異なるクラスの各コンポーネントを分離することができました。しかし、時にはわずか5〜10行のコードのためのクラスを作成することは愚かなようです。私はたくさんの私的な状態を渡す必要があるので、醜いでしょう。私はヘルパー機能をテストすることができません。とにかくこれをやるべきでしょうか?私はそれを吸うと公共のドロー()のみをテストする必要がありますか?または、他の解決策がありますか?

+0

これは役に立つかもしれません[どのようにJavaScriptでユニットテストプライベート関数へ](http://philipwalton.com/articles/how-to-unit-test-private-functions-in-javascript/) – amirnissim

答えて

9

外側のスコープから内部関数(プライベート)にアクセスする方法はありません。内部関数をテストする場合は、テスト目的でのみパブリックメソッドを追加することを検討してください。 antのようないくつかの種類のビルド環境を使用している場合は、本番用のjavascriptファイルを前処理して、それらのテスト関数を削除することができます。

実際、Javascriptはオブジェクト指向言語です。それは単にstatitcally型付けされたものではありません。

+5

実際、Javascriptはオブジェクト指向ではなく、プロトタイプベースです。 OOの振る舞いを模倣することができます。 – pcjuzer

+11

@pcjuzer、Javascriptはオブジェクト指向ですが、ほとんどの人がよく知っている古典的なオブジェクト指向言語とは異なる実装です。 –

+0

どのようにすべてのセキュリティを失うことなくテストパブリックメソッドを追加しますか? –

0

オブジェクト指向言語では、通常、テストクラスがテストするクラスから継承することにより、プロテクトメソッドをテストします。

もちろん、Javascriptは実際にオブジェクト指向言語ではなく、このパターンは継承を考慮していません。

私はあなたのメソッドを公開する必要があると思うか、それらをテストするユニットをあきらめるかのどちらかと思います。

+0

C#では、派生クラスはその基本クラスのプライベートメンバーにアクセスできません。それは他の言語とは違うのですか? –

+0

Javaでは、プライベートメンバーまたはメソッドにサブクラスでアクセスすることはできません。 –

+0

申し訳ありませんが、私は保護を意味しました。 –

1

実際には簡単な方法があります。 ajaxを使用してスクリプトをロードし、プライベート関数を公開する関数を挿入することができます。 qUnitとjQueryを使用する例hereがあります。しかし、純粋なJavascriptを使って同じことを簡単に達成できると確信しています。

+0

これは、クロージャーコンパイル済み(またはuglifiedなど)のバージョンを単体テストする場合に問題になります。私はコンパイルされたバージョンのみをテストします。コンパイルに問題がある場合、私は知る必要があります。 –

3

私にも同様の問題があります。私が思いついた解決策は、私が好きなものではありませんが、それは仕事をして、私が見つけることができるより良い解決策はありません。テストへ

function Graph() 
{ 
    this.Test = function _Test(expressionStr) { return eval(expressionStr); } 

    var private_data; 
    function draw_legend() { ... } 
    function draw_plot() { ... } 
    function helper_func() { ... } 
    ... 
} 

var g = new Graph(); 
g.Test("helper_func()") == something; 
g.Test("private_data") == something2 
5

私のソリューションは、ハックの少しだけです。QUnit例:私は宣言したQunitテストHTMLの上部に

:あなたは

を確認することができQUnitで

if(TEST_AVAILABLE){ 
    this.test={ 
     hasDraft:hasDraft, 
     isInterpIdIn:isInterpIdIn, 
     // other private methods 
    }; 
} 

var TEST_AVAILABLE = true; 

テスト可能なクラスで私はこのようなフラグメントを持っています

test("hello booth", function() { 
    var b = new Booth(); 
    ok(b); 
    ok(b.test); 
    ok(!b.test.hasDraft()); 
}); 
+0

ここの提案に似てhttp://www.mikeball.us/blog/how-to-make-testable-private-functions-in-javascript – jlarson

+0

@jlarsonのURLはhttp://www.mikeball.usに変更されたようです/ blog/testable-private-methods-in-javascript / –

0

唯一の正しいオプションがあります:異なるビルド

関連する問題