【发布时间】:2016-01-09 01:13:10
【问题描述】:
这是我的 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();
});
});
这是我的 karma 配置文件的 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 模块中(以及 @987654340 @,我只加载SpPageApp模块)。
【问题讨论】:
-
既然已经模拟了服务,为什么还要称其为假货?只需调用模拟服务即可。
-
@DavidL Phil 在此处发布的答案:stackoverflow.com/questions/34623322/… 在模拟服务时调用了一个假的,所以我决定也使用它(我是 Jasmine 的新手,所以我认为 Phil 所做的是最佳实践)。我相信这是因为
ctrl.add()将一个函数传递给BaseService.add.sp应该被回调。 -
他的答案的替代方案如下: mockBaseService = { cerrorMessages: 'whatever', add: function() { // 不管 add 函数应该做什么 } };在这种情况下,您无需使用 spy 对象创建额外的开销,而是简单地覆盖服务并将覆盖的模拟服务注入您的控制器,因为您关心的只是测试控制器,而不是服务。
标签: angularjs jasmine karma-jasmine