Javascript 事件处理程序后带有异步请求的AngularJS测试控制器(Jasmine)
我有一个控制器:Javascript 事件处理程序后带有异步请求的AngularJS测试控制器(Jasmine),javascript,angularjs,asynchronous,jasmine,Javascript,Angularjs,Asynchronous,Jasmine,我有一个控制器: myApp.controller('someCtrl', function ($scope, myAsyncService, $routeParams) { var foo_id = $routeParams.foo_id; $scope.foo = 0; $scope.bar = false; $scope.$on('that_happened', function (event, plan) {
myApp.controller('someCtrl', function ($scope, myAsyncService, $routeParams) {
var foo_id = $routeParams.foo_id;
$scope.foo = 0;
$scope.bar = false;
$scope.$on('that_happened',
function (event, plan) {
myAsyncService.save({id: foo_id}).$promise.then(function (res) {
$scope.bar = true;
$location.path('/foo/' + res.id);
});
}
);
});
发出“that_happend”事件后,服务调用async方法,我想测试执行回调后更改的$scope和位置:
describe('my module', function () {
var res_mock = 2,
myAsyncService_mock = {
save: function () {}
};
describe('someCtrl', function(){
var $location,
$scope,
$subscope,
deferred,
promise_mock,
ctrl,
$q;
beforeEach(
inject(function ($rootScope, _$location_, _$q_) {
$q = _$q_;
$location = _$location_;
$scope = $rootScope.$new();
$subscope = $scope.$new();
deferred = $q.defer();
promise_mock = {
$promise: deferred.promise
};
spyOn(myAsyncService_mock, 'save').andReturn(promise_mock);
ctrl = $controller('someCtrl',
{
$scope: $scope,
$location: $location,
myAsyncService: myAsyncService_mock
}
);
})
);
it('should call save method of service and set bar to true and goto /foo/:saved_foo.id ', function () {
var saved_foo_mock = {
id: 3
}
$scope.foo = 11;
$scope.bar = false;
$subscope.$emit('that_happened');
deferred.resolve(saved_foo_mock);
expect(myAsyncService_mock.save).toHaveBeenCalled();
expect($scope.bar).toBe(true);
expect($location.path()).toBe('/foo/' + saved_foo_mock.id);
});
});
});
但测试失败,错误为“预期false为true”。似乎承诺回调未执行或在expect之后执行
我曾尝试以异步方式对其进行测试,但结果是相同的-测试因超时而失败:
runs(function () {
$scope.bar = false;
$subscope.$emit('that_happened');
});
waitsFor(function () {
deferred.resolve(saved_foo_mock);
return $scope.bar;
}, 'bar should be true', 500);
runs(function () {
expect(myAsyncService_mock.save).toHaveBeenCalled();
expect($location.path()).toBe('/foo/' + saved_foo_mock.id);
});
发生什么事了?为什么$scope和location path没有更改?这个问题帮助了我:
将myAsyncService_mock移动到beforeach block,并添加了$scope.$digest调用,最后运行:
beforeEach(
inject(function ($rootScope, _$location_, _$q_) {
.
.
.
myAsyncService_mock = {
save: function () {
deferred = $q.defer();
promise_mock = {
$promise: deferred.promise
};
return promise_mock;
}
};
.
.
.
})
);
it('', function(){
.
.
.
$subscope.$emit('that_happened');
deferred.resolve(saved_foo_mock);
$scope.$digest();
.
.
.
})