BeforeEachブロックを使用するコーヒースクリプトでジャスミンテストを記述しようとしています。これはcoffeescriptの変数スコープに関する問題にぶつかります。これが私が書きたいものです:
describe 'PhoneDetailCtrl', () ->
beforeEach () ->
scope = angular.scope()
$browser = scope.$service('$browser')
it 'should fetch phone detail', () ->
scope.params = {phoneId:'xyz'}
$browser.xhr.expectGET('phones/xyz.json').respond({name:'phone xyz'})
ctrl = scope.$new(PhoneDetailCtrl)
expect(ctrl.phone).toEqualData({})
$browser.xhr.flush()
expect(ctrl.phone).toEqualData({name:'phone xyz'})
ただし、これは機能しません。scope
および$browser
は、最も内側のスコープでvar
を使用して宣言されます。つまり、一度beforeEach
に含まれ、次にit
ブロックに含まれます。変数を初期化することで、変数を正しいスコープで宣言することができますが、これは非常に奇妙に見えます。
describe 'PhoneDetailCtrl', () ->
$browser = {}
scope = {}
beforeEach () ->
scope = angular.scope()
$browser = scope.$service('$browser')
it 'should fetch phone detail', () ->
scope.params = {phoneId:'xyz'}
...
これは機能しますが、コンパイルするJavaScriptは実際には
describe('PhoneListCtrl', function() {
var $browser, ctrl, scope;
$browser = {};
ctrl = {};
scope = {};
必要なのはvar $browser, ctrl, scope;
。これをコーヒースクリプトでもっと簡潔に書くことはできますか?
あなたはそれを正しい方法で行っています。
これは CoffeeScriptのドキュメント で説明されています。それが作成するJSについては心配しません。はい、自分で書くのは少し面倒ですが、これは、CoffeeScriptのようなリライターを使用するときに必要なものの1つです。
ただし、かなりいいオプションがいくつかあります。
必要に応じて、変数を現在のコンテキストに置くことができます(好奇心が強い人にとってはjasmine.Specオブジェクトです)。これは、変数を置くのに比較的安全で適切な場所です...上書きしないでください コンテキスト内の既存の変数 。):
describe 'PhoneDetailCtrl', () ->
beforeEach () ->
@scope = angular.scope()
@$browser = @scope.$service('$browser')
it 'should fetch phone detail', () ->
@scope.params = {phoneId:'xyz'}
#... etc
物事を保存する独自の変数を設定することもできます
describe 'PhoneDetailCtrl', () ->
setup = {}
beforeEach () ->
setup.scope = angular.scope()
setup.$browser = setup.scope.$service('$browser')
it 'should fetch phone detail', () ->
setup.scope.params = {phoneId:'xyz'}
#... etc
テストは次のように書くことができます:
describe "MyGame", ->
mygame = null
beforeEach inject (_MyGame_) ->
mygame = _MyGame_
it "should have two players", ->
expect(mygame.opponents.length).toEqual 2
構文がより明確になりました-グローバル化する必要はありません。