Jul*_*ian 9 javascript angularjs karma-runner angular-mock angular-providers
我正在尝试测试使用的模块angular-google-maps.它失败了,因为angular.mock.inject找不到uiGmapGoogleMapApiProvider:
Error: [$injector:unpr] Unknown provider: uiGmapGoogleMapApiProviderProvider <- uiGmapGoogleMapApiProvider
Run Code Online (Sandbox Code Playgroud)
我无法弄清楚出了什么问题.这是简化的测试用例:
'use strict';
describe('this spec', function() {
beforeEach(module('uiGmapgoogle-maps'));
it('tries to configure uiGmapGoogleMapApiProvider', inject(function(uiGmapGoogleMapApiProvider) {
expect(uiGmapGoogleMapApiProvider.configure).toBeDefined();
}));
});
Run Code Online (Sandbox Code Playgroud)
整个过程可以作为GitHub中可立即运行的Angular项目提供.如果您发现问题,请在此处回答Stack Overflow.如果您还向GitHub存储库提交拉取请求,则可获得奖励积分.
这里有两个陷阱相互作用,两者都与 Angular-google-maps 无关。
\n第一个陷阱在于服务和提供商之间的区别。该文档指出,服务、工厂、值和常量是提供者的特例。对于像我这样的相对初学者来说,这似乎表明提供者和服务可以以相同的方式在任何地方进行依赖注入。然而,事实恰恰相反:在任何可以注入依赖项的地方,您可以注入提供者或服务,但不能同时注入两者。
\n造成这种划分的原因在于配置时间和运行时间之间的严格分离(请参阅模块文档)。提供程序在配置期间可用,而服务在运行时可用。运行时间在配置时间结束后开始。.config和.provider块在配置时执行,而大多数其他类型的块在运行时执行。以下代码片段说明了提供者和服务定义之间的关系,改编自提供者文档:
myModule.provider(\'myServiceProvider\', [\'injectedProvider\', function MyServiceProvider(injectedProvider) {\n // configuration time code depending on injectedProvider\n\n this.$get = ["injectedService", function MyService(injectedService) {\n // run time code depending on injectedService\n }];\n\n // more configuration time code\n}]);\nRun Code Online (Sandbox Code Playgroud)\n正如您所看到的,服务是在提供者中定义的。提供者是在配置时定义的(外部块,function MyServiceProvider)并且可能依赖于其他提供者。可以在运行时使用提供者的.$get方法从提供者中提取服务,如内部块 ( function MyService) 所定义,并且可能依赖于其他服务。提供程序不能是服务的注入依赖项,反之亦然,但您可以将服务定义嵌套在提供程序定义中,如上所示,使其间接依赖于提供程序。当您使用块定义“独立”服务时angular.module(...).service,Angular 会在您背后执行类似上述代码的操作。
另一个陷阱是angular.mock.inject,它inject来自我问题中的单元测试,只能进行运行时注入。对于配置时注入,您必须通过创建具有配置时依赖性的新模块来执行“真实的事情”,即非模拟注入。这就是姆吉玛德所暗示的。Andr\xc3\xa9 Eife 发布了一个关于如何执行此操作的简短教程,我通过其他问题答案底部的链接找到了该教程。
总之,这里是解决我的问题的代码:
\n\'use strict\';\n\ndescribe(\'this spec\', function() {\n var gmapProvider;\n\n beforeEach(function() {\n angular.module(\'testAssist\', [\'uiGmapgoogle-maps\'])\n .config(function(uiGmapGoogleMapApiProvider) {\n gmapProvider = uiGmapGoogleMapApiProvider;\n });\n module(\'testAssist\'); // angular.mock.module\n inject(); // angular.mock.inject\n });\n\n it(\'tries to configure uiGmapGoogleMapApiProvider\', function() {\n expect(gmapProvider.configure).toBeDefined();\n });\n});\nRun Code Online (Sandbox Code Playgroud)\n\'testAssist\'夹具 ( ) 中的模块存在beforeEach的唯一目的是对 具有配置时间依赖性uiGmapGoogleMapApiProvider,因此我可以在局部变量中捕获后者gmapProvider。随后对module和 的调用inject是簿记技巧,以确保 的config块\'testAssist\'得到执行。由于捕获,测试用例 () 中不需要进行任何注入it,我只需验证提供者是否有一个configure方法。请注意,第一个angular.module调用是常规模块定义,而第二个module调用是来自模拟框架 ( ) 的特殊构造angular.mock。
我已将上述解决方案推送到GitHub上的fix1分支。
\n| 归档时间: |
|
| 查看次数: |
516 次 |
| 最近记录: |