2013-06-14 11 views
9

明らかになったモジュールパターンとの簡単なロマンスの後、私はユニットテストモジュールに関しては後退を実現するようになりました。しかし、私がモジュールをテストする私のアプローチであるのか、何らかの形の回避策があるのか​​どうかは決めることができません。私は(ジャスミンを使用して)publicMethodBにpublicMethodA介してつながるさまざまな経路をテストしたい場合モジュールパターンの表示 - ジャスミンによるユニットテスト

var myWonderfulModule = (function() { 
    function publicMethodA (condition) { 
    if(condition === 'b') { 
     publicMethodB(); 
    } 
    } 

    function publicMethodB() { 
    // ... 
    } 

    return { 
    methodA : publicMethodA, 
    methodB : publicMethodB 
    } 
}()); 

は、以下のコードを検討してください。

it("should make a call to publicMethodB when condition is 'b'", function() { 
    spyOn(myWonderfulModule , 'publicMethodB'); 
    myWonderfulModule.publicMethodA('b'); 
    expect(myWonderfulModule.publicMethodB).toHaveBeenCalled(); 
}); 

私が正しく理解していれば、publicMethodBのコピーを変更することはできませんクロージャ内があります:私はそうのような小さなテストを書くかもしれません。私はその後myWonderfulModule.publicMethodBを変更しても:myWonderfulModule.publicMethodAを呼び出す

myWonderfulModule.publicMethodB = undefined; 

はまだB.

の元のバージョンを実行します

上記の例では、もちろん単純化であるが、私はどこにそれを考えることができますシナリオがたくさんありますメソッドを介してテスト条件付きパスを単体テストすると便利です。

これは明らかなモジュールパターンの制限ですか、単なる単体テストの誤用ですか?私にはどのような回避策がありますか?私はRequireJSのようなものに移動することを検討しているか、非モジュラーコードに戻すことを検討しています。

アドバイスありがとうございます。

答えて

8

あなたはクロージャのinternメソッドをテストできません。そして、あなたはまたそれを偵察するべきではありません。あなたのモジュールをブラックボックスと考えてください。あなたは何かを入れて、あなたは何かを得る。あなたがテストしなければならないのは、モジュールから出てくるものがあなたが期待するものであるということです。

あなたのモジュール内のメソッドをスパイすることはあまり意味がありません。それについて考える。あなたはスパイして、テストに合格します。これで機能が変更され、バグが作成されます。テストは引き続き実行されますが、まだ関数が呼び出されていますが、バグについては言及していません。あなたが言うことをテストするだけでは、内部のメソッドが原因でスパイする必要はありません。モジュールの結果が期待通りであれば、呼び出されるのは暗黙のことです。

あなたのケースでは、入ることはなく、何も出てこない。これはあまり意味がありませんが、私はあなたのモジュールがDOMとやりとりしたり、ajax呼び出しを行うと信じています。これはあなたがテストできるもの(DOM)か、スパイするべきもの(ajax)です。

また、Inversion of Control and Dependency Injectionに慣れ親しんでください。これらは、モジュールのテストをはるかに容易にするパターンです。

0

publicMethodA()からpublicMethodB()を呼び出すときにキーワード "this"を使用すると、それは機能します。例:

var myWonderfulModule = (function() { 
    function publicMethodA (condition) { 
     if(condition === 'b') { 
      this.publicMethodB(); 
     } 
    } 

    function publicMethodB() { 
     // ... 
    } 

    return { 
     methodA : publicMethodA, 
     methodB : publicMethodB 
    } 
}()); 
関連する問題