2013-10-15 17 views
13

私はディレクティブから$ emitをスパイしようとしていますが、何とか$ emitを聞くためにスパイを得ることができません。

これは私の指示のコードであるコントローラ:

$scope.$on('send', function() { 
    console.log('called'); 
    $scope.$emit('resultSend', {'ok': true, 'data': ''}); 
}); 

これは私のユニットテストである:

var $rootScope, $compile, elm, element; 

beforeEach(inject(function ($injector) { 
    $rootScope = $injector.get('$rootScope'); 
    $compile = $injector.get('$compile'); 
    elm = angular.element('<test></test>'); 
    element = $compile(elm)($rootScope); 
})); 


it('should listen for the send broadcast and emit the resultSend', function() { 
    spyOn($rootScope, '$emit'); 
    $rootScope.$broadcast('send'); 
    expect($rootScope.$emit).toHaveBeenCalledWith('resultSend'); 
}); 

にconsole.log出力( '' と呼ばれる)はカルマによってプリントアウトされ、だから私はユニットテストのブロードキャストイベントが動作すると思います。

$ emitは放送していないが、アップしている場合はどうすればそれを捕まえることができますか?もしそうでなければ、どうすればこのケースを処理できますか?

+4

あなたは '$ rootScope'を監視し、' $ scope'に対して '$ emit'を呼び出しています。 –

答えて

13

hereによれば、$emit$broadcastの違いを理解していることになります。しかし、私は問題が$scope$rootScopeのあなたの使用にあると思う。 $rootScopeは、スコープ階層の最上位になります。コントローラーの$scopeがネストされたコントローラーであることを意味します。つまり、コントローラー内の$scopeは、そのアプリケーションの$rootScopeの子であることを意味します(私はすべてのコードを見ることができずにスニペットを見るだけです)。

そのため、あなたのユニットテストが$rootScope.$emit機能でスパイクすると、実際にコントローラの$scope.$emit()コールでスパイされていません。それらの2つの「スコープ」は同じではなく、異なっています。だから、コントローラーに提供する$scopeを嘲笑してから、spyOnを実行する必要があります。例えば

、あなたのbeforeEachに:

var ctrl, scope; 

beforeEach(function() { 
    module('<INSERT YOUR CONTROLLERS MODULE NAME HERE>'); 
    inject(function($rootScope, $controller) { 
     scope = $rootScope.$new(); 
     ctrl = $controller('<CTRL NAME HERE>', {$scope: scope}); 
    }); 
}); 

このコードは実際には「モック」スコープ変数を作成し、あなたが、その後でスパイや他のものを行うことができ、あなたのコントローラにそのオブジェクトを提供します。など:

spyOn(scope, '$emit'); 
// do whatever triggers the "$emit" call 
expect(scope.$emit).toHaveBeenCalledWith('resultSend'); 

あなたの問題を解決する必要があります。それがもっと説明を必要とするかどうか私に教えてください。

+0

非常にクリア、ありがとう! – Maarten

+0

この場合のコントローラは何ですか? – 9blue

+0

情報をいただきありがとうございます。私はジャスミンを使ってVue2をテストしていますが、同じことをしました。コンポーネントがcloseを出力するので、emitをテストする方法を知りたがっています。 ) constコンストラクタ= Vue.extend(Component); vm = newコンストラクタ({propsData})。$ mount(); spyOn(vm、 '$ emit'); // "$ emit"コールをトリガーするものを実行します。 expect(vm。$ emit).toHaveBeenCalledWith( 'onComponentClose'); ありがとう! –

3

コントローラがあるディレクティブの場合は、そのディレクティブとは別にコントローラでテストすることができます。これはMVCアーキテクチャ全体のポイントです.Vから別々にCをテストすることができます);

つまり、プレーンジェーンコントローラのテスト仕様です。

もう1つのヒント:beforeEach()ブロック(つまりスパイなど)ですべての設定を行い、it()ブロックでアサーションを実行する必要があります。

最後に、設定しているスパイが、テストしているコントローラに渡しているスコープにあることを確認してください。

+0

ポインタに感謝し、あなたの答えも正しいとはいえ、私は1つだけにフラグを立てることができます;-) – Maarten

+1

人々は彼らが継続するために必要な情報を得る限り、それは実際に "ポイント" –

+0

本当、まだそれはcatch'em'allの楽しいと思う;-) – Maarten

関連する問題