Unit testing 为什么$provide仅在';angular.mock.module';功能,并且$q仅在';angular.mock.inject';功能?
我正在模拟AngularJS单元测试的服务。我正在使用Unit testing 为什么$provide仅在';angular.mock.module';功能,并且$q仅在';angular.mock.inject';功能?,unit-testing,angularjs,dependency-injection,jasmine,Unit Testing,Angularjs,Dependency Injection,Jasmine,我正在模拟AngularJS单元测试的服务。我正在使用$provide服务将“真实”服务替换为模拟服务(其中一个可用): 这个很好用。但是,我不喜欢使用angular.mock.module函数仅仅是为了引用$provide服务,然后在下面的angular.mock.inject函数中使用该服务。但是如果我直接将$provide作为参数添加到angular.mock.inject函数中,则会出现“未知提供程序”错误 我突然想到,我可以将所有模拟代码放在angular.mock.module函数中
$provide
服务将“真实”服务替换为模拟服务(其中一个可用):
这个很好用。但是,我不喜欢使用angular.mock.module
函数仅仅是为了引用$provide
服务,然后在下面的angular.mock.inject
函数中使用该服务。但是如果我直接将$provide
作为参数添加到angular.mock.inject
函数中,则会出现“未知提供程序”错误
我突然想到,我可以将所有模拟代码放在angular.mock.module
函数中。但是,$q
引用也有类似的问题,我需要它,因为我的模拟服务必须返回一个承诺
换句话说,如果我在angular.mock.module
函数中添加$q
参数,那么我也会得到一个“未知提供程序”错误
有没有办法简化这一点?很明显,我的方法很有效,但不知怎么的,我感觉不太对劲。我觉得我不理解为什么一些提供程序在
inject
函数中可用,而其他提供程序在模块
函数中可用。您不能在inject
函数中使用$provide
,因为前者注册提供程序供后者使用。看一看:
describe('...', function() {
beforeEach(function() {
module(function($provide) {
$provide.constant('someValue', 'foobar');
});
inject(function(someValue) {
var value = someValue; // will be 'foobar';
});
});
});
不过,您可以这样编写测试:
describe('...', function() {
var serviceMock;
beforeEach(function() {
serviceMock = {
someMethod: function() { ... }
};
module(function($provide) {
$provide.value('service', serviceMock);
});
inject(function(service) {
...
});
});
});
事实上,在注入$provide
之前,您甚至不需要实现模拟服务:
beforeEach(function() {
serviceMock = {};
module(function($provide) {
$provide.value('service', serviceMock);
});
inject(function(service) {
...
});
});
it('tests something', function() {
// Arrange
serviceMock.someMethod = function() { ... }
// Act
// does something
// Assert
expect(...).toBe(...);
});
这是一个主要用于说明上述内容的示例。当我不得不包装一个使用
$q
且看起来相当干净的服务时,这对我很有效:
var _ServiceToTest_;
beforeEach(function () {
module('module.being.tested');
module(function ($provide) {
$provide.factory('ServiceToMock', function ($q, $rootScope) {
var service = ...;
// use $q et al to heart's content
return service;
});
});
inject(function (_ServiceToTest_) {
ServiceToTest = _ServiceToTest_;
});
});
it('...', function () { /* code using ServiceToTest */ });
诀窍是使用
$provide.factory
而不是$provide.value
这非常好,而且很有效。。。只要你不使用承诺。这是一个plunk,展示了我的原始示例:这是一个用您建议的技术更新的fork:模拟服务没有被分配;看起来好像有什么东西干扰了时间安排。@Holf你可以用一个承诺,但你需要先把事情转一转。请查看此更新内容。@Holf您无法在模块
函数中获得$q
服务的实例,因为Angular没有向其中注入任何服务。正确的方法是使用inject
功能。据我所知,这是设计的。@futuoadangular.module
用于定义模块,而angular.mock.module
用于将现有模块加载到内存中,以便测试可以访问其内容(服务、工厂、指令等)<代码>模拟。模块还用于配置注入器,以便您可以为任何可注入服务提供模拟对象。有关详细信息,请参阅。@FutuoADmodule
是angular.mock.module
的全局别名,如文档中所述:此函数也发布在窗口上,以便于访问。
。
var _ServiceToTest_;
beforeEach(function () {
module('module.being.tested');
module(function ($provide) {
$provide.factory('ServiceToMock', function ($q, $rootScope) {
var service = ...;
// use $q et al to heart's content
return service;
});
});
inject(function (_ServiceToTest_) {
ServiceToTest = _ServiceToTest_;
});
});
it('...', function () { /* code using ServiceToTest */ });