我的服务非常简单:
'use strict';
angular.module('sapphire.orders').service('deliveryDatesService', service);
function service() {
return {
clearAddressReason: clearAddressReason,
getMinDate: getMinDate
};
//////////////////////////////////////////////////
function clearAddressReason(model, dateReasons, reasons) {
if (model.manualAddress) {
model.overrideDates = true;
reasons.date = dateReasons.filter(function (item) {
return item.value === 'D4';
})[0];
} else {
reasons.address = null;
if (!reasons.date || reasons.date.value === 'D4') {
reasons.date = null;
model.overrideDates = false;
}
}
};
function getMinDate(model) {
var now = new Date();
// If we are not overriding dates, set to today
if (!model.overrideDates) return now;
// If dates are overriden, then the min date is today + daysToDispatch
return new Date(now.setDate(now.getDate() + model.daysToDispatch));
};
};
它没有依赖关系,所以我想测试方法。 所以我试图创建一个这样的规范:
'use strict';
describe('Service: deliveryDatesService', function () {
beforeEach(module('sapphire.orders'));
var service,
reasons,
dateReasons;
beforeEach(inject(function (deliveryDatesService) {
console.log(deliveryDatesService);
service = deliveryDatesService;
reasons = {};
dateReasons = [{ value: 'D4' }];
}));
it('can create an instance of the service', function () {
expect(service).toBeDefined();
});
it('if manual delivery address is true, then override dates should be true', function () {
var model = { manualDeliveryDate: true };
service.clearAddressReason(model, dateReasons, reasons);
expect(model.overrideDates).toBe(true);
});
it('if manual delivery address is false, then override dates should be false', function () {
var model = { manualDeliveryDate: false };
service.clearAddressReason(model, dateReasons, reasons);
expect(model.overrideDates).toBe(false);
});
it('minimum date cannot be less than today', function () {
var model = { };
var minDate = service.getMinDate(model);
var now = new Date();
expect(minDate).toBeGreaterThan(now);
});
});
但我的服务总是未定义的。有人可以告诉我,我做错了吗?
更新
因此,事实证明这与一个或多个以某种方式干扰的服务有关。 在我的 karma.conf.js 中,我已经宣布了所有的bower应用程序,然后是:
'src/app/app.module.js',
'src/app/**/*module.js',
'src/app/**/*constants.js',
'src/app/**/*service.js',
'src/app/**/*routes.js',
'src/app/**/*.js',
'test/spec/**/*.js'
我在我的脚本目录的根目录中创建了一个测试服务,然后创建了一个spec文件以查看它是否已创建。它向我呻吟着一个完全没有关系的文件中的引用错误。它对这段代码抱怨不已:
angular.module('sapphire.core').factory('options', service);
function service($rootScope) {
return {
get: get,
save: save
};
//////////////////////////////////////////////////
function get() {
if (Modernizr.localstorage) {
var storageData = angular.fromJson(localStorage.options);
if (storageData) {
return angular.fromJson(storageData);
}
}
return {
background: {
enabled: true,
enableSnow: true,
opacity: 0.6
}
};
};
function save(options) {
if (Modernizr.localstorage) {
localStorage.options = angular.toJson(options);
$rootScope.$options = get();
}
};
};
声明Modernizr未定义。 我将代码更改为:
angular.module('sapphire.core').factory('options', service);
function service($rootScope) {
return {
get: get,
save: save
};
//////////////////////////////////////////////////
function get() {
if (typeof Modernizr == 'object' && Modernizr.localstorage) {
var storageData = angular.fromJson(localStorage.options);
if (storageData) {
return angular.fromJson(storageData);
}
}
return {
background: {
enabled: true,
enableSnow: true,
opacity: 0.6
}
};
};
function save(options) {
if (typeof Modernizr == 'object' && Modernizr.localstorage) {
localStorage.options = angular.toJson(options);
$rootScope.$options = get();
}
};
};
它开始工作了。但我的另一个测试不是。 所以我将 karma.conf.js 中的引用更改为:
'src/app/app.module.js',
'src/app/orders/orders.module.js',
'src/app/orders/shared/*.js',
'test/spec/**/*.js'
它开始工作了。 这让我相信我的应用程序在某处出现了问题。也许像 Modernizr 这样的另一个参考。我仍然有一个悬而未决的问题。不依赖于其他服务的服务如何干扰? 我认为值得注意的是,每个服务,控制器,指令都在它自己的文件中,并且它们都遵循这种结构:
(function () {
'use strict';
angular.module('sapphire.core').factory('options', service);
function service($rootScope) {
return {
get: get,
save: save
};
//////////////////////////////////////////////////
function get() {
if (typeof Modernizr == 'object' && Modernizr.localstorage) {
var storageData = angular.fromJson(localStorage.options);
if (storageData) {
return angular.fromJson(storageData);
}
}
return {
background: {
enabled: true,
enableSnow: true,
opacity: 0.6
}
};
};
function save(options) {
if (typeof Modernizr == 'object' && Modernizr.localstorage) {
localStorage.options = angular.toJson(options);
$rootScope.$options = get();
}
};
};
})();
我想知道因为我将它们包装在执行自己的匿名函数中,是什么导致了这个问题?
*解决方案*
所以最后我发现究竟是什么导致了这个问题。这确实与 karma.conf.js 中的文件有关。我已经告诉它加载所有文件,并且在那里有一些它不喜欢的东西。 经过一段时间的游戏后,我终于找到了它的样子,并认为我会分享它以防万一其他人来到这里。
问题是路线。我正在使用 ui.router ,看来在测试中使用它们会失败。 我将文件部分更改为:
'src/app/app.module.js',
'src/app/**/*module.js',
'src/app/**/*constants.js',
'src/app/**/*service.js',
'src/app/**/*controller.js',
//'src/app/**/*routes.js',
'test/spec/**/*.js'
正如您所看到的,我已将路径文件注释掉了。如果我把它们带回来,一切都会失败。
答案 0 :(得分:0)
我认为你的内部deliveryDatesService变量正在隐藏外部变量。
为避免这种情况,您可以尝试按照以下网站上的规范在内部服务变量周围加下下划线:
https://docs.angularjs.org/api/ngMock/function/angular.mock.inject
寻找
'解决参考文献(下划线包裹)'
在该页面上。
然后你的代码看起来像这样:
beforeEach(inject(function (_deliveryDatesService_) {
console.log(_deliveryDatesService_);
service = _deliveryDatesService_;
reasons = {};
dateReasons = [{ value: 'D4' }];
}));
此外,您需要确保在karma.conf.js中声明所有必需的文件和目录,以便测试框架可以使用它们。