我有一个控制器可以完成两件事:
1)履行承诺时执行函数($ q.then)
2)在'onLocationChangedStart'
事件被触发时执行函数
在我的单元测试中,我想测试(1)的功能。我这样做是通过执行$RootScope.$apply()
来触发承诺解决方案。很遗憾,事实证明$rootScope.$apply()
也会发出'onLocationChangedStart'
事件,其中url = http://server/
(这是在角度代码中)。
显然这是一个问题,因为它会解雇(2),即使这不是我想要的特定单元测试。
有没有任何简单的方法可以不涉及修改原始代码只是为了让单元测试运行? (例如,我可以将函数(2)放在$scope
上,然后在运行测试之前将其模拟为null。但这似乎是hackish)
更新了清理代码示例:
angular.module('myMod')
.controller("ctrl", function ($scope, $log, myService, $location) {
myService.doSomething()
.then(function () {
//does something
})
})
$scope.$on('$locationChangeStart', routeChange);
function routeChange(event, currentUrl, nextUrl) {
//does something
};
})
//Jasmine unit test
describe('test', function () {
var $scope,
ctrl,
$rootScope;
beforeEach(function () {
module("myMod");
module("myServiceMock");
inject(function (_$rootScope_, $controller, _myService_) {
$rootScope = _$rootScope_;
$scope = $rootScope.$new();
ctrl = $controller('ctrl', {
$scope: $scope
});
});
});
it("Should set startup values appropriately", inject(function () {
//doing this triggers both the myService promise AND the location event listener
$rootScope.$apply();
}));
答案 0 :(得分:1)
您可以使用$scope.$digest()
代替$scope.$apply()
。 $digest()
只会在当前范围内执行监控的表达式,而$apply()
会运行$rootScope.$digest()
:
it("Should set startup values appropriately", function() {
$scope.$digest();
// promise resolved
// onLocationChangedStart event not fired
});