这是我的test_sp.js文件:
describe('Controller: MainCtrl', function() {
var ctrl, mockBaseService;
beforeEach(function() {
mockBaseService = {
cerrorMessages: 'whatever',
sp: "[{'spName': 'Test'}]",
// Calls back if errors.
add: jasmine.createSpyObj('BaseService.add', ['sp']),
logout: jasmine.createSpy('BaseService.logout'),
// Calls back if errors.
fetch: jasmine.createSpyObj('BaseService.fetch', ['selfsp'])
};
mockBaseService.add.sp.and.callFake(function(something, cb) {
cb(); // execute the callback immediately
});
mockBaseService.fetch.selfsp.and.callFake(function(something, cb) {
cb(); // execute the callback immediately
});
module('SpPageApp');
// Let ctrl = MainCtrl and override BaseService in MainCtrl to be
// the mockBaseService above.
inject(function($controller) {
ctrl = $controller('MainCtrl', {
BaseService: mockBaseService
});
});
});
it('should have an add function', function() {
expect(ctrl.add).toBeDefined();
});
});
这是我的业力配置文件的file
数组:
files: [
'../angular.js',
'node_modules/angular-mocks/angular-mocks.js',
'../w.js',
'../sp.js',
'../s.js',
'../base.js',
'tests/test_sp.js',
],
最后,这是我的sp.js
,其中包含SpPageApp
模块:
angular.module("SpPageApp", ["BaseApp"])
.controller("MainCtrl", ["$http", "$window", "BaseService", function($http, $window, BaseService) {
var self = this;
BaseService.fetch.selfsp(function() {
self.sp = BaseService.sp;
self.cerrorMessages = BaseService.cerrorMessages;
});
self.add = function() {
BaseService.add.sp(self.sp, function() {
self.cerrorMessages = BaseService.cerrorMessages;
});
};
self.logoutUser = function() {
BaseService.logout();
};
}]);
我做karma start
来测试代码,我收到一个错误说:
Chromium 47.0.2526 (Ubuntu 0.0.0) Controller: MainsCtrl should have an add function FAILED
TypeError: Cannot read property 'and' of undefined
at Object.<anonymous> (/home/a/Documents/CMS/CMSApp/static/js/karma/tests/test_sp.js:20:45)
TypeError: Cannot read property 'add' of undefined
at Object.<anonymous> (/home/a/Documents/CMS/CMSApp/static/js/karma/tests/test_sp.js:36:20)
Chromium 47.0.2526 (Ubuntu 0.0.0): Executed 1 of 1 (1 FAILED) (0 secs / 0.006 secChromium 47.0.2526 (Ubuntu 0.0.0): Executed 1 of 1 (1 FAILED) ERROR (0.034 secs / 0.006 secs)
错误说它无法读取已定义的属性add
,并指向此行:
expect(ctrl.add).toBeDefined();
并且它无法读取未定义的属性and
,并指向此行:
mockBaseService.fetch.selfsp.and.callFake(function(something, cb) {
为什么Jasmine说ctrl
和mockBaseService.fetch.selfsp
在代码中定义时未定义?
编辑:对于它的价值,w.js
,sp.js
和s.js
(正在加载的业力)都有名为MainCtrl
的控制器,但每个控制器都在其自己的文件中和AngularJS模块(在test_sp.js
中,我只加载SpPageApp
模块。)
答案 0 :(得分:2)
正如我的评论中所提到的,您可以直接模拟服务并避免使用间谍。此外,您可以告诉$ injector使用您的模拟服务而不是真正的实现,允许您在解析服务时直接注入模拟,这将取代您的正常实现。
假设您的BaseService存在于SpPageApp模块中:
mockBaseService = {
cerrorMessages: 'whatever',
sp: "[{'spName': 'Test'}]",
add: function (something, cb) { cb() },
...
};
module('BaseApp', function($provide) {
$provide.value('BaseService', mockBaseService);
});
module('SpPageApp');
inject(function($controller) {
ctrl = $controller('MainCtrl', {
});
});
要进行测试,如评论中所述,您仍然希望使用间谍来确保成功调用它。
it('should have an add function', function() {
spyOn(mockBaseService, 'add');
ctrl.add();
expect(mockBaseService.add).toHaveBeenCalled();
});