2012-10-30 10 views
6

私は事実上同じテストをたくさんしています。 DRYとスキャン可能性のために、テストを単一の関数に抽象化してから、その関数をいくつかのパラメータで呼び出すことができます。関数はitを呼び出して、仕様をスイートに追加します。関数内でジャスミン仕様を定義しても、beforeEachを適用することは可能ですか?

仕様が他の仕様と同じ方法で実行されず、共通機能で定義された仕様の前にbeforeEachが呼び出されていないことを除いて、動作するようです。

define(['modules/MyModule','jasmine/jasmine'], function(MyModule) { 

    describe('myModule', function() { 

     function commonTests(params) { 
      it('should pass this test OK', function() { 
       expect(true).toBe(true); 
      }); 

      it('should fail because module is undefined', function() { 
       expect(module[params.method]()).toBe('whatever'); 
      }); 
     } 

     var module; 

     beforeEach(function() { 
      module = new MyModule(); 
     }); 

     describe('#function1', function() { 
      commonTests({ 
       method: 'function1' 
      }); 
     }); 

     describe('#function2', function() { 
      commonTests({ 
       method: 'function2' 
      }); 
     }); 

    }); 

}); 

これを行うとbeforeEachafterEachの機能を維持する方法はありますか?

UPDATE:私は私の例が間違って得たよう

が見える、申し訳ありません。

define(['modules/MyModule'], function(MyModule) { 

    function commonTests(params) { 
     it('will fail because params.module is undefined', function() { 
      expect(typeof params.module).toBe('object'); 
      expect(typeof params.module[params.method]).toBe('function'); 
     }); 

     it('has a few tests in here', function() { 
      expect(true).toBe(true); 
     }); 
    } 


    describe('MyModule', function() { 

     var module; 

     beforeEach(function() { 
      module = new MyModule(); 
     }); 

     describe('#function1', function() { 
      commonTests({ 
       module: module, 
       method: 'function1' 
      }); 
     }); 

     describe('#function2', function() { 
      commonTests({ 
       module: module, 
       method: 'function2' 
      }); 
     }); 

    }); 
}); 

私はmoduleの値は常に最初の例のようにmoduleの現在の値を使用するのではなく、commonTestsへの呼び出しの一部として保存されるので、それは失敗だと思う:ここで失敗した場合です。

答えて

4

ありがとう!私が使用している最終的な解決策は非常に似ています

define(['modules/MyModule'], function(MyModule) { 

    var module; 

    function commonTests(params) { 
     it('will not fail because module is shared', function() { 
      expect(typeof module).toBe('object'); 
      expect(typeof module[params.method]).toBe('function'); 
     }); 

     it('has a few tests in here', function() { 
      expect(true).toBe(true); 
     }); 
    } 


    describe('MyModule', function() { 

     beforeEach(function() { 
      module = new MyModule(); 
     }); 

     describe('#function1', function() { 
      commonTests({ 
       method: 'function1' 
      }); 
     }); 

     describe('#function2', function() { 
      commonTests({ 
       method: 'function2' 
      }); 
     }); 

    }); 
}); 

が、あなたは少し異なるアプローチを取る必要がありますcommonTestsに引数としてmoduleに渡すとで異なる機能を持っている能力を持っているために必要な場合各itブロック:

define(['modules/MyModule'], function(MyModule) { 

    var module; 

    function commonTest1(params) { 
     expect(typeof module).toBe('object'); 
     expect(typeof module[params.method]).toBe('function'); 
    } 

    function commonTest2(params) { 
     expect(true).toBe(true); 
    } 


    describe('MyModule', function() { 

     beforeEach(function() { 
      module = new MyModule(); 
     }); 

     describe('#function1', function() { 

      it('will not fail because module is shared', function() { 
       commonTest1({ method: 'function1' }); 
      }); 

      it('has a few tests in here', function() { 
       commonTest2({ method: 'function1' }); 
      }); 

     }); 

     describe('#function2', function() { 

      it('will not fail because module is shared', function() { 
       commonTest1({ method: 'function2' }); 
      }); 

      it('has a few tests in here', function() { 
       commonTest2({ method: 'function2' }); 
      }); 

     }); 

    }); 
}); 

共通のテストを含む関数の実行がbeforeEachは、そのコールバックを実行した後まで延期されるこの方法です。

0

はい、このシナリオは問題なく機能します。私たちはgated checkinsでテストを実行するためにchutzpahを使用しており、afterEach機能がなければテストは失敗します。

しかし、defineの行は、require.jsのように見えます。私たちにはいくつかの問題がありました... MyModuleundefinedであるか、または期待どおりに定義されていないと思います。 beforeEachメソッドでブレークポイントを設定しようとしましたが、呼び出されたかどうか、そして値がMyModuleの場合はありますか?どのようにテストを呼びますか?

define行を使用せずにコードを実行すると、beforeEach関数が4xと呼ばれるようになりました。 Btw私はchutzpah.console.exeを使ってテストを呼び出しました。

編集:

ええ、今私のPCで問題を再現することができます。それは私にははるかに明確です。 最初にすべての変数が最初に定義されていないので、moduleは未定義です。次に、beforeEachdescribeを使用して、ジャスミンで関数を登録します。ジャスミンは最初にdescribeに渡された

function() { 
    commonTests({ 
     module: module, 
     method: 'function1' 
    }); 
} 

から始まります。 module: moduleの行では、の参照var moduleが新しいオブジェクトのプロパティmoduleにコピーされています。これはこれまでのところundefinedを参照しています。 beforeEachコールバックが呼び出されるとき、それは正しい値にvar moduleの参照を変更しますが、間違った参照が既に...

をコピーされた私はfunction commonTestsvar moduleを移動しようとしたし、代わりにparams.moduleのテストでその変数を使用し、彼らは期待どおりに通過します。私はそれがあなたの環境のオプションであるかどうかはわかりませんが、それが助けてくれることを願っています。

挨拶し、 アンドレアス私の最初の例では、実際に働いていたことを指摘しアンドレアスへ

+0

興味深いことに、もちろんあなたはもちろんそうです:それはrequire.jsです。私の知っていることは、MyModuleは 'commonTests'(これは省略していません)にはない、それを使っている他のテストがあるので、ロードされているということです。 'commonTests'でデバッガを実行し、' module'の値をチェックすると 'undefined'となります。それは 'commonTests'の外のテストで正しい値を持っています... ありがとう! –

+0

他のテストは、2つの 'describe'コールの一番下に位置していると思いますよね?私はJSの 'var'スコープについて何かを読んだことを覚えています。場合によっては、関数内で 'var'で定義された変数は、' var'ステートメントの後でしか利用できません。ここに当てはまる場合は、 'commonTests'にあるグローバルな' module'(存在しない)にアクセスしようとします。おそらく、 'varモジュール 'と' beforeEach'を周囲の 'describe'の先頭に移動しようとすることができます。 – Andreas

+0

ありがとうAndreas、私は見て、私のコードに例を比較し、それはわずかに異なっていた。私は質問に更新を投稿しました... –

関連する問題