我有一条指令,该指令的行为应有所不同,具体取决于自初始化以来经过的时间:
am.directive('showText', () => ({
restrict: 'E',
replace: true,
scope: {
value: '@'
},
controller: ($scope, $timeout) => {
console.log('timeout triggered');
$scope.textVisible = false;
let visibilityCheckTimeout = $timeout(() => {
if (parseInt($scope.value, 10) < 100) {
$scope.textVisible = true;
}
}, 330);
// Clear timeout upon directive destruction
$scope.$on('$destroy', $timeout.cancel(visibilityCheckTimeout));
},
}));
问题是,当我尝试使用Jasmine进行测试时,我似乎找不到以任何方式触发此超时的方法。已经尝试了$timeout.flush()
和$timeout.verifyNoPendingTasks()
(如果我要注释flush
调用,实际上会引发错误)。但是它仍然没有触发超时的回调执行
describe('showText.', () => {
let $compile;
let $rootScope;
let $scope;
let $timeout;
const compileElement = (rootScope, value = 0) => {
$scope = rootScope.$new();
$scope.value = value;
const element = $compile(`
<show-text
value="value"
></show-text>
`)($scope);
$scope.$digest();
return element;
};
beforeEach(() => {
module('app.directives.showText');
inject((_$compile_, _$rootScope_, _$timeout_) => {
$compile = _$compile_;
$rootScope = _$rootScope_;
$timeout = _$timeout_;
});
});
it(`Process lasts > 0.33s. Should show text.`, () => {
const VALUE = 30;
const element = compileElement($rootScope, VALUE);
const elementContent = element.find('.show-text__content');
$timeout.flush(1000);
$timeout.verifyNoPendingTasks();
$rootScope.$digest();
expect(element.isolateScope().textVisible).toBeTruthy();
expect(elementContent.length).toEqual(1);
expect(elementContent.text().trim()).toBe('Example text');
});
});
测试失败。
找不到我在做什么错。关于如何正确测试这种情况的任何提示?
谢谢。
UPD
经过一番调查,我发现在此特定的测试用例中,在compileElement
功能上,服务value
没有对属性进行评估$compile
。和等于"value"
。我已经使用同一个函数十次了,但无法$scope.value
理解,为什么它不像以前那样具有的属性。
发生这种情况的原因是$timeout.cancel(visibilityCheckTimeout)
无条件立即启动。相反,它应该是
$scope.$on('$destroy', () => $timeout.cancel(visibilityCheckTimeout));
可以做一些事情来提高可测试性(除了在$timeout
这里充当一次性示波器观察员并要求用它代替之类的事实之外)。
$timeout
可以成功[\监视\:
beforeEach(module('app', ($provide) => {
$provide.decorator('$timeout', ($delegate) => {
var timeoutSpy = jasmine.createSpy().and.returnValue($delegate);
angular.extend(timeoutSpy, $delegate);
spyOn(timeoutSpy, 'cancel').and.callThrough();
return timeoutSpy;
});
}));
私有$timeout
回调可以暴露给作用域。
$scope._visibilityCheckHandler = () => {
if (parseInt($scope.value, 10) < 100) {
$scope.textVisible = true;
}
};
$timeout($scope._visibilityCheckHandler, 330);
这样,可以监听所有呼叫并获得全部覆盖:
let directiveScope;
...
const element = $compile(`...`)($scope);
directiveScope = element.isolateScope();
spyOn(directiveScope, '_visibilityCheckHandler').and.callThrough();
$scope.$digest();
...
expect($timeout).toHaveBeenCalledWith(directiveScope._visibilityCheckHandler, 330);
expect($timeout.cancel).not.toHaveBeenCalled();
在这种情况下,这里不需要为带有flush
延迟参数的’> =
\0.33s’和’<0.33s’制定单独的规范,其$timeout
内部工作已经在Angular规范中进行了测试。此外,回调逻辑可以与$timeout
规范分开进行测试。
问题内容: 我正在使用Jasmine编写AngularJS的指令测试,并与它们一起使用templateUrl:https : //gist.github.com/tanepiper/62bd10125e8408def5cc 但是,当我运行测试时,我得到了要点中包含的错误: 从我在文档中阅读的内容来看,我认为自己做得正确,但是事实并非如此-我在这里想念的是什么? 谢谢 问题答案: 如果您使用的是ng
问题内容: 我有一个遗留应用程序,该应用程序通过jQuery将一些内容插入了DOM。我希望代码库的遗留部分负责编译它插入DOM中的html。 我可以使用来编译初始html ,但是除非我从指令内部调用,否则不会编译指令模板或templateUrl添加的任何DOM元素。 我在这里做错了什么? 链接到小提琴: http://jsfiddle.net/f3dkp291/15/ index.html app
问题内容: 根据Michal Charemza帖子编辑。 我有一个代表angularui模态对话框的服务: 如果用户单击对话框中的“确定”,则在调用delete方法时将执行。 问题是我无法对此进行单元测试。 这是我的考验。我已经正确注入了q服务,但是我不确定应该从间谍那里返回什么… 但是我正在接受。这意味着…部分没有执行。我想念什么? 问题答案: 要模拟返回承诺的函数,它还需要返回承诺,然后需要将
问题内容: 我有一个已定义的AngularJS指令。我正在尝试与Jasmine进行单元测试。 根据此建议,我的JasmineJavaScript如下所示: 当我在Jasmine spec错误中运行此命令时,出现以下错误: 我想要的只是让templateUrl原样加载- 我不想使用。我相信这可能与使用ngMock而不是ngMockE2E有关。如果是罪魁祸首,如何使用后者而不是前者? 提前致谢! 问题
问题内容: 在以下情况下如何使用包含。目的是在html(部分)文件中使用标记,而不是在模板中(在指令内)定义标记。 我在这里找到了一个很棒的树指令。( 来源)原文: http //jsfiddle.net/n8dPm/ 我没有在指令中定义模板,而是尝试使用包含在内的内容。我还将Angular更新为1.2.0.rc2。更新时间:http://jsfiddle.net/aZx7B/2/ 低于错误 Ty
问题内容: 我只是从angularjs开始,并且正在努力将一些旧的JQuery插件转换为Angular指令。我想为我的(元素)指令定义一组默认选项,可以通过在属性中指定选项值来覆盖这些默认选项。 我一直在寻找其他人这样做的方式,并且在angular-ui库中ui.bootstrap.pagination似乎做了类似的事情。 首先,所有默认选项都在一个常量对象中定义: 然后,将实用程序功能附加到指令