问题
我正在测试一个指令。该指令在范围变量上有一个监视,但从不调用监视。将$watch
调用直接放在单元测试中是可行的。为什么$watch
不调用指令中的?
谢谢!
细节
这是我的原始测试。该指令中有一个手表,看着'reEvalCreateDate'
. 它从未被调用,并且日期字符串始终为空。
测试中没有 watch 语句
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();
}));
....