这是一个让我好几天的问题。带有代码示例的Plunkr在这里:http://plnkr.co/edit/QHJCyKfM2yFyCQzB68GS?p=preview
基本上,我有一个正在侦听事件并返回值的服务工厂。
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.$on("myEvent", function(args, value) {
$scope.myEventCalled = true;
});
});
app.factory('myService', function($rootScope){
var mysvc = {}
mysvc.testVar = true
$rootScope.$on('otherEvent', function(args, value){
$rootScope.rootCalled = true;
mysvc.testVar = false;
});
return mysvc
});
我的测试是:
describe('Testing a Hello World controller', function() {
var $scope = null;
var svc = null
//you need to indicate your module in a test
beforeEach(module('plunker'));
it('should be able to see settings in service', inject(function($rootScope, $controller) {
$scope = $rootScope.$new();
inject(function($httpBackend, myService) {
svc = myService
})
expect(svc).toBeDefined();
expect(svc.testVar).toBe(true);
}));
it('should invoke otherEvent when "otherEvent" broadcasted in service', inject(function($rootScope, $controller) {
$scope = $rootScope.$new();
inject(function($httpBackend, myService) {
svc = myService
})
$scope.$broadcast('otherEvent');
expect(svc.testVar).toBe(false);
}));
});
第一次测试通过,但第二次测试失败,因为它无法触发事件并访问修改后的值。
我知道如何使用控制器对此进行测试,但验证该值已从服务中更改已经逃脱了我。我会很感激任何建议。
答案 0 :(得分:1)
myService
正在聆听$rootScope
,但在第二次测试中,该事件已在$scope
上播出。由于$broadcast
将事件名称向下发送到所有子范围及其子级,因此不会达到$rootScope
。
在第二次测试中将其更改为此,它将起作用:
$rootScope.$broadcast('otherEvent');
但是,在测试控制器时,建议使用其依赖项的模拟版本,并仅隔离测试控制器自身的功能。以同样的方式,每项服务都应该有自己的规范。