如何使用注入服务测试 Angular 1.6 组件?
Posted
技术标签:
【中文标题】如何使用注入服务测试 Angular 1.6 组件?【英文标题】:How to test Angular 1.6 component with injected service? 【发布时间】:2017-06-18 11:38:54 【问题描述】:我想测试我的 Angular 组件,它在语法上基于 John Papa's styleguide:
'use strict';
angular.module('MyModule')
.component('MyCmpnt', MyCmpnt())
.controller('MyCtrl', MyCtrl);
function MyCmpnt()
return
restrict: 'E',
templateUrl: 'myPath/myTemplate.html',
bindings:
foo: '=',
bar: '<'
,
controller: 'MyCtrl',
controllerAs: 'vm'
;
MyCtrl.$inject = ['MyService'];
function MyCtrl (MyService)
// controller logic
如您所见,我想注入 MyService
到控制器中,并在服务 上的一个函数中spy。
我的测试代码:
'use strict';
describe('component: MyCmpnt', function ()
var $componentController,
MyService;
beforeEach(module('MyModule'));
beforeEach(module(function ($provide)
$provide.value('MyService', MyService);
spyOn(MyService, 'serviceFunc').and.callThrough();
));
beforeEach(inject(function (_$componentController_)
$componentController = _$componentController_;
));
it('should initiate the component and define bindings', function ()
var bindings =
foo: 'baz',
bar: []
;
var ctrl = $componentController('MyCmpnt', null, bindings);
expect(ctrl.foo).toBeDefined();
);
);
但是,此设置让我遇到以下错误:
TypeError: undefined is not a constructor (evalating '$componentController('MyModule', null, bindings)')
【问题讨论】:
没有“MyModule”组件... @estus:MyModule
是一个模块,由一个组件MyCmpnt
和对应的控制器MyCtrl
组成。不过你是什么意思?
你在做$componentController('MyModule'...
,并且没有MyModule组件。这正是错误消息所说的。它是 MyCmpnt。不是我的模块。
你说得对,谢谢,这是一个输入错误,但由于 $componentController
未定义,上述错误仍然存在。这意味着注入甚至还没有执行。
这不加起来。 is not a constructor
不仅意味着未定义的东西,而且未定义构造函数。 Angular 仅将构造函数用于控制器和 service
服务。我建议仔细检查您是否在运行的规范中更正了此问题,因为我从上面的代码中看不到此错误的其他合理解释。如果问题仍然存在,请考虑提供可以复制此错误的 plunk/fiddle。顺便说一句,您在上面的代码中未定义 MyService
变量(spyOn(MyService...
会抛出),这意味着发布的代码与实际代码不同。
【参考方案1】:
上面的代码有$componentController('MyModule'...
,没有MyModule
组件。
MyService
变量在调用spyOn(MyService...
时未定义。这将引发错误,阻止应用程序正确引导。
如果测试平台使用 PhantomJS,这可能会导致 beforeEach
块中的错误抑制,为了正确报告错误,建议使用 Chrome Karma 启动器。
如果问题是 MyService
在定义模拟服务时未定义,则可以将其就地定义为存根:
beforeEach(module(function ($provide)
$provide.value('MyService',
serviceFunc: jasmine.createSpy().and.callThrough()
);
));
【讨论】:
以上是关于如何使用注入服务测试 Angular 1.6 组件?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Angular-Fullstack 生成的 Angular 1.5 组件中注入依赖项
是否可以将服务注入 Angular 1.5 组件的 templateUrl 属性?
向组件注入服务后,如何解决加载 Angular 应用程序的问题?