将 angular.element('*[ng-app]').injector() 与 karma + jasmine 一起使用
Use angular.element('*[ng-app]').injector() with karma + jasmine
我有一个 angular 1 应用程序,我正在以一种非常自定义的风格编写,以便切换到 angular 2 更加直接,例如,不使用 angular.service()
在 angular 中创建服务并使用正常的依赖注入方式,而是创建原始打字稿(或 ES2015 样式)class
。当 运行 在浏览器中正常运行时,以下所有代码都可以正常运行。
问题特别在于一行:
Auth.jwtHelper = angular.element('*[ng-app]').injector().get('jwtHelper');
karma 抛出的错误是:
Uncaught TypeError: Cannot read property 'get' of undefined
这自然意味着没有找到喷油器。同样,当 运行 在浏览器中正常时,这绝对 100% 有效。另外值得注意的是,在 jQuery DOM 就绪事件 $(function{...});
上发生的服务实例化时调用此行
模块引导以使用 <html ng-app="myApp">
的正常记录方式完成 ng-app
指令可以移动到 <body>
因为应用程序不需要 [=20] 中的范围=] 元素像以前一样。也许这就是 karma 在这个电话上窒息的原因。
更新:将 ng-app
移动到 <body>
没有产生任何变化
我已经研究了一些 angular 模拟源代码和 .d.ts 文件,试图找到任何替代方法来获取应用程序的注入器,但没有看到任何东西我现在还可以使用。
我正在寻找的是 建设性的 建议,不需要使用 angular 典型注入模式的替代方案,或任何其他可能有用的花絮.
正如预期的那样,由于这是一种非常不典型的方法,google 结果并不是很有帮助。
更新:
关于这个问题的更多背景信息
export class Auth{
public static jwtHelper;
public static init(){
Auth.jwtHelper = angular.element('*[ng-app]').injector().get('jwtHelper');
}
}
$(Auth.init);
正如您在此处看到的那样,init 方法是在 DOM 准备就绪时调用的,而不是从单元测试中调用的。我无法提供单元测试的描述块,因为它与我的单元测试分开运行。它是应用程序加载的一部分。
我意识到这是一个很老的问题,但看到我 运行 遇到了同样的问题,我想我会 post 为下一个人提供我的解决方案。
你需要做的是猴子补丁 angular.element
所以它 returns 注入器:
beforeEach(angular.mock.inject(['$injector', function(injector) {
// save original
var original = angular.element;
// replace with our own
angular.element = function() {
// proxy all calls to the original
var result = original.apply(this, arguments);
// add the injector to the result
result.injector = function() { return injector; };
return result;
}
// also add all the angular.element properties to our fake or some other stuff will break
for (let prop in original) {
angular.element[prop] = original[prop];
}
}]));
在您的规范中 angular.mock.module()
声明之后立即添加该位,您就可以开始了!
我遇到了同样的错误,并且能够通过以下方法解决这个问题...
注意:我使用的是 Typescript
let SampleController, $injector;
(<any>angular).mock.inject(($componentController, _$injector_) => {
$injector = _$injector_;
// angular.element(document.body).injector() doesn't behave correctly because we don't have ng-app in the DOM for unit tests. Spy the injector response instead.
spyOn(angular.element.prototype, "injector").and.callFake(() => {
return $injector;
});
// angular.element is triggered in the super of SampleController
SampleController = $componentController("SampleComponent", null);
});
我认为它更直接一些,因为您专注于 angular.element
的原型
我有一个 angular 1 应用程序,我正在以一种非常自定义的风格编写,以便切换到 angular 2 更加直接,例如,不使用 angular.service()
在 angular 中创建服务并使用正常的依赖注入方式,而是创建原始打字稿(或 ES2015 样式)class
。当 运行 在浏览器中正常运行时,以下所有代码都可以正常运行。
问题特别在于一行:
Auth.jwtHelper = angular.element('*[ng-app]').injector().get('jwtHelper');
karma 抛出的错误是:
Uncaught TypeError: Cannot read property 'get' of undefined
这自然意味着没有找到喷油器。同样,当 运行 在浏览器中正常时,这绝对 100% 有效。另外值得注意的是,在 jQuery DOM 就绪事件 $(function{...});
模块引导以使用 <html ng-app="myApp">
的正常记录方式完成 ng-app
指令可以移动到 <body>
因为应用程序不需要 [=20] 中的范围=] 元素像以前一样。也许这就是 karma 在这个电话上窒息的原因。
更新:将 ng-app
移动到 <body>
没有产生任何变化
我已经研究了一些 angular 模拟源代码和 .d.ts 文件,试图找到任何替代方法来获取应用程序的注入器,但没有看到任何东西我现在还可以使用。
我正在寻找的是 建设性的 建议,不需要使用 angular 典型注入模式的替代方案,或任何其他可能有用的花絮.
正如预期的那样,由于这是一种非常不典型的方法,google 结果并不是很有帮助。
更新:
关于这个问题的更多背景信息
export class Auth{
public static jwtHelper;
public static init(){
Auth.jwtHelper = angular.element('*[ng-app]').injector().get('jwtHelper');
}
}
$(Auth.init);
正如您在此处看到的那样,init 方法是在 DOM 准备就绪时调用的,而不是从单元测试中调用的。我无法提供单元测试的描述块,因为它与我的单元测试分开运行。它是应用程序加载的一部分。
我意识到这是一个很老的问题,但看到我 运行 遇到了同样的问题,我想我会 post 为下一个人提供我的解决方案。
你需要做的是猴子补丁 angular.element
所以它 returns 注入器:
beforeEach(angular.mock.inject(['$injector', function(injector) {
// save original
var original = angular.element;
// replace with our own
angular.element = function() {
// proxy all calls to the original
var result = original.apply(this, arguments);
// add the injector to the result
result.injector = function() { return injector; };
return result;
}
// also add all the angular.element properties to our fake or some other stuff will break
for (let prop in original) {
angular.element[prop] = original[prop];
}
}]));
在您的规范中 angular.mock.module()
声明之后立即添加该位,您就可以开始了!
我遇到了同样的错误,并且能够通过以下方法解决这个问题...
注意:我使用的是 Typescript
let SampleController, $injector;
(<any>angular).mock.inject(($componentController, _$injector_) => {
$injector = _$injector_;
// angular.element(document.body).injector() doesn't behave correctly because we don't have ng-app in the DOM for unit tests. Spy the injector response instead.
spyOn(angular.element.prototype, "injector").and.callFake(() => {
return $injector;
});
// angular.element is triggered in the super of SampleController
SampleController = $componentController("SampleComponent", null);
});
我认为它更直接一些,因为您专注于 angular.element
的原型