我有一个服务,它使用缓存检索数据并回退到$ http,并且我试图使用jasmine spies在控制器规范中模拟对服务的调用。但是,当我调用scope.$digest
时,正在调用实际服务并正在进行HTTP调用。
我已尝试使用[$rootScope|scope].[$apply|$digest]()
的所有组合,我的HTTP调用仍在进行中。但是,如果我从我的间谍那里返回一个除了一个承诺之外的东西,比如一个字符串,我会得到一个错误,then
未定义为一个函数,所以看来间谍是否成功地存在该函数?
beforeEach(inject(function ($controller, $rootScope) {
scope = $rootScope.$new();
// Should be called by each test after mocks and spies have been setup
startContoller = function() {
$controller('SearchCtrl', {
$scope: scope,
$stateParams: { q: 'test' }
});
};
}));
it('sets error message when no results', inject(function(QuestionService, $q) {
var deferred;
spyOn(QuestionService, 'search').and.callFake(function() {
deferred = $q.defer();
deferred.reject();
return deferred.promise;
});
startContoller();
scope.$digest();
expect(scope.error).toBe(true);
}));
.controller('SearchCtrl', ['$scope', '$stateParams', 'QuestionService',
function($scope, $stateParams, QuestionService) {
var query = $stateParams.q;
$scope.page = 1;
QuestionService.search(query, $scope.page).then(function(questions) {
if (questions.length === 0) {
$scope.error = true;
$scope.errorMessage = 'No Results';
} else {
$scope.questions = questions;
}
}, function() {
$scope.error = true;
});
}]);
答案 0 :(得分:0)
dmahapatro的评论是要走的路。
当您使用$ controller(' SearchCtrl' ...)检索控制器时,您的服务已经在您的" it"块被执行,因此监视它没有任何效果。
您应该在$ controller调用中注入模拟服务。 此外,不需要你的startController()函数,因为调用$ controller将执行控制器的逻辑。
var QuestionServiceMock, deferred;
beforeEach(inject(function ($controller, $rootScope) {
scope = $rootScope.$new();
QuestionServiceMock = jasmine.createSpyObj('QuestionService', ['search']);
QuestionServiceMock.search.andCallFake(function () {
deferred = $q.defer();
deferred.reject();
return deferred.promise;
});
$controller('SearchCtrl', {
$scope: scope,
$stateParams: { q: 'test' },
QuestionService: QuestionServiceMock
});
}));
it('sets error message when no results', inject(function(QuestionService, $q) {
scope.$apply();
expect(scope.error).toBe(true);
}));