問題
ディレクティブをテストしています。ディレクティブにはスコープ変数の監視がありますが、監視は呼び出されません。呼び出しを単体テスト$watch
内に直接配置すると機能します。$watch
ディレクティブの が呼び出されないのはなぜですか?
ありがとう!
詳細
これが私のオリジナルのテストです。ディレクティブには、 を見て、時計が含まれてい'reEvalCreateDate'
ます。呼び出されることはなく、日付文字列は常に空です。
ウォッチステートメントを含まないテスト
it('should inject a date string', function()
{
scope.reEvalCreateDate = reEvalCreateDateAsNumber;
expect(elm.text()).toBe('');
scope.$digest();
expect(elm.text()).toBe(new Date(reEvalCreateDateAsNumber).toUTCString());
});
テストとして、時計を単体テストに入れました。正しく呼び出され、テストに合格します。
ソース (時計自体をテストに入れるように変更)
it('should inject a date string', function()
{
scope.$watch('reEvalCreateDate', function(newValue, oldValue)
{
var date = new Date(newValue);
scope.dateString = date.toUTCString();
dump(scope.dateString)
});
scope.reEvalCreateDate = reEvalCreateDateAsNumber;
expect(elm.text()).toBe('');
scope.$digest();
expect(elm.text()).toBe(new Date(reEvalCreateDateAsNumber).toUTCString()); //This passes!
});
ディレクティブ ソース コード
これは、watch ステートメントを含むディレクティブ コードです。
link: function(scope, element, attrs)
{
scope.$watch('show',function(shouldShow){
console.log('should show reeval timer? ' + shouldShow);
if(shouldShow) {
$(element).fadeIn('slow');
}
else if(shouldShow === false){
$(element).fadeOut('slow');
}
});
//this statement's never called when testing!!
scope.$watch('reEvalCreateDate', function(newValue, oldValue)
{
var date = new Date(newValue);
scope.dateString = date.toUTCString();
});
}
セットアップコード
テスト用のすべての初期化コードは次のとおりです。
var elm, scope;
var reEvalCreateDateAsNumber = 1359487598000;
beforeEach(inject(function($rootScope, $compile)
{
// we might move this tpl into an html file as well...
elm = angular.element(
'<reeval-timer show="showTimePopup" re-eval-create-date="reEvalCreateDate" class="re-eval-timer" ng-cloak >' +
'{{dateString}}' +
'</reeval-timer>');
scope = $rootScope.$new();
$compile(elm)(scope);
scope.$digest();
}));
アップデート
コメントによると、ディレクティブにスコープを設定しているとは思いません。それを可能にするAPIは何も見当たりません。$compile
スコープを設定しようとして、呼び出しのいくつかの順列を試しました。
html から要素を作成し、それをコンパイルに渡します。運がない。
elm = angular.element(
'<div>' +
'<tabs>' +
'<pane title="First Tab">' +
'first content is {{first}}' +
'</pane>' +
'<pane title="Second Tab">' +
'second content is {{second}}' +
'</pane>' +
'</tabs>' +
'</div>');
scope = $rootScope;
$compile(elm)(scope);
最初に要素を作成することによって
var element = $compile('<p>{{total}}</p>')(scope);
問題がディレクティブにスコープを設定していないということである場合、エラーは mybeforeEach
にある可能性が高いと思います。ここにあります:
describe('Reeval Timer', function()
{
var elm, scope,element;
var reEvalCreateDateAsNumber = 1359487598000;
beforeEach(inject(function($rootScope, $compile)
{
// we might move this tpl into an html file as well...
elm = angular.element(
'<reeval-timer show="showTimePopup" re-eval-create-date="reEvalCreateDate" class="re-eval-timer" ng-cloak >' +
'</reeval-timer>');
scope = $rootScope.$new();
element = $compile(elm.contents())(scope);
scope.$digest();
}));
....