Это мой контроллер:
angular.module("AuthenticationApp", ["BaseApp"])
.controller("AuthCtrl", ["$http", "BaseService", function($http, BaseService) {
var self = this;
BaseService.fetch.stuffs()
.then(function(data) {
self.stuffs = data;
});
}]);
Это мой BaseService
(фабрика, которую мне нужно издеваться):
angular.module("BaseApp", ["ngRoute"])
.factory("BaseService", ["$http", "$q", function($http, $q) {
var self = this;
self.fetch = {
stuffs: function() {
return $http.get("/api/stuffs/")
.then(function(response) {
return response.data;
});
}
};
return self;
}]);
Я понятия не имею, с чего начать. Я пробовал следующее:
describe('Controller: AuthCtrl', function() {
var ctrl, mockBaseService;
beforeEach(function() {
mockBaseService = {
stuffs: 'test',
fetch: {
stuffs: function() {
return {
then: function() {
return {stuffs: "stuffs"};
},
}
},
},
};
spyOn(mockBaseService.fetch, 'stuffs');
module('BaseApp', function($provide) {
$provide.value('BaseService', mockBaseService);
});
module('AuthenticationApp');
inject(function($controller) {
ctrl = $controller('AuthCtrl', {
});
});
});
it('BaseService.fetch.stuffs should be called on page load', function() {
expect(mockBaseService.fetch.stuffs).toHaveBeenCalled();
expect(ctrl.stuffs).toBe({stuffs: "stuffs"});
});
});
Но когда я тестирую этот код, я получаю сообщение об ошибке:
TypeError: Cannot read property 'then' of undefined
at new <anonymous> (/home/user/Documents/ebdjango/ebdjangoapp/static/js/home.js:15:11)
home.js
строка 15 это строка в контроллере:
return $http.get("/api/stuffs/")
.then(function(response) { // line 15
return response.data;
});
Как правильно издеваться над этим?
Изменить: я прочитал документацию, упомянутую в комментариях, и изменил mockBaseService
на это:
describe('Controller: AuthCtrl', function() {
var ctrl, mockBaseService;
beforeEach(function() {
// create promise
var deferred = $q.defer();
var promise = deferred.promise;
// make promise.then return {stuffs: "stuffs"}
promise.then(function(value) { return {stuffs: "stuffs" }; });
mockBaseService = {
stuffs: 'stuffs',
fetch: {
stuffs: function() {
return promise;
},
},
};
spyOn(mockBaseService.fetch, 'stuffs');
module('BaseApp', function($provide) {
$provide.value('BaseService', mockBaseService);
});
module('AuthenticationApp');
inject(function($controller) {
ctrl = $controller('AuthCtrl', {
});
});
});
it('BaseService.fetch.stuffs should be called on page load', inject(function($rootScope) {
deferred.resolve('test');
$rootScope.$apply();
expect(mockBaseService.fetch.stuffs).toHaveBeenCalled();
expect(ctrl.stuffs).toBe({stuffs: "stuffs"});
}));
});
Но это возвращает ошибку ReferenceError: $q is not defined
. Я попытался ввести _$q_
вот так:
beforeEach(inject(function(_$q_) {
$q = _$q_;
// ... everything else goes here... //
Но потом я получаю сообщение об ошибке Error: Injector already created, can not register a module!
. Здесь: инжектор уже создан. не могу зарегистрировать модуль пишет, что эту проблему можно решить, если мы выполним module('someApp')
до inject($someDependency)
. Но я не могу
module('BaseApp', function($provide) {
$provide.value('BaseService', mockBaseService);
});
перед вводом _$q_
, так как $q
используется для mockBaseService
. Куда мне идти отсюда?