加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

AngularJS单元测试 – 用于注入依赖项的各种模式

发布时间:2020-12-17 07:14:09 所属栏目:安全 来源:网络整理
导读:我是单元测试的新手,主要是从我找到的例子中学习.问题是我看到了很多不同的模式,很难理解它们之间的差异.以及如何将这些模式组合到各种用例中.下面是一个这样的模式: var $rootScope,$window,$location; beforeEach(angular.mock.module('security.service'
我是单元测试的新手,主要是从我找到的例子中学习.问题是我看到了很多不同的模式,很难理解它们之间的差异.以及如何将这些模式组合到各种用例中.下面是一个这样的模式:

var $rootScope,$window,$location;
    beforeEach(angular.mock.module('security.service','security/loginModal.tpl.html'));

    beforeEach(inject(function(_$rootScope_,_$location_) {
        $rootScope = _$rootScope_;
        $location = _$location_;
    }));

    var service,queue;
    beforeEach(inject(function($injector) {
        service = $injector.get('security');
        queue = $injector.get('securityRetryQueue');
    }));

因此,从这种模式中,我发现Angular核心服务/提供者应该注入下划线模式,其他第三方依赖项或我自己的依赖项应该使用$injector.get()模式完成.这有效吗?我注意到我可以使用Angular核心服务执行$injector.get()并且它仍然可以工作,所以也许只是这样做的惯例?另外,beforeEach中的’security / loginModal.tpl.html’有什么意义(angular.mock.module(‘security.service’,’security / loginModal.tpl.html’));?我知道它是一个添加到模板缓存的HTML模板但是angular.mock.module做了什么呢?

我也看到过这种不太常见的模式,它会在上面的逻辑中抛出一个小扳手:

beforeEach(inject(function($injector,_$location_) {
        security = $injector.get('security');
        $location = _$location_;
    }));

如果我可以像注入$location这样的注入回调添加服务,这似乎是一种更简单的引用依赖关系的方式.我为什么不这样做?

这是另一种模式:

beforeEach(function() {
        module('security.service',function($provide) {
            $provide.value('$window',$window = jasmine.createSpyObj('$window',['addEventListener','postMessage','open']));
        });

        inject(function(security) {
            service = security;
        });
    });

根据我的理解,这种模式的重点是使用模拟的$window初始化“security.service”模块.这是有道理的,但我如何使用以前的模式适应这种模式?即如何模拟’security / loginModal.tpl.html’,如何将我的Angular核心依赖项注入其他依赖项?

最后,我可以和不能在嵌套的描述和注入块中注入什么?假设我无法将模拟服务复制到我正在测试的模块中,这是否安全?那么我可以注入什么以及用例是什么?

如果有一个确定的AngularJS单元测试初始化??文档源可以帮助回答这些问题,请指出.

解决方法

I’ve gleaned that Angular core services/providers should be injected with the underscore pattern where as other 3rd party dependencies or my own dependencies should be done using the $injector.get() pattern

你可以使用其中之一.下划线模式只是一种方便的方法,可以避免与同名的局部变量发生冲突.考虑以下

var $rootScope,myService,http; // these are local variables

beforeEach(inject(function(_$rootScope_,_myService_,$http) {
    $rootScope = _$rootScope_; // underscores to avoid variable name conflict
    myService = _myService_; // same here with your custom service
    http = $http; // local variable is named differently to service
}));

If I can just add services to the inject callback like this code does with $location,that seems like a simpler way of referencing dependencies. Why should I not do this?

你应该 :)

Also,what is the point of ‘security/loginModal.tpl.html’ in beforeEach(angular.mock.module('security.service','security/loginModal.tpl.html'));?

据我所知,除非你有一个具有该名称的实际模块,例如

angular.module('security/loginModal.tpl.html',[])

这会失败. angular.mock.module只应传递模块名称,实例或匿名初始化函数.

how do I mock ‘security/loginModal.tpl.html’

理想情况下,你不应该.单元测试应测试代码的API …交互点,通常由对象上可公开访问的方法和属性定义.

如果您只是想阻止Karma尝试通过HTTP加载模板(通常来自指令测试),您可以使用模板预处理器,如karma-ng-html2js-preprocessor

Lastly,what can I and can’t inject in nested describe and it blocks? Is it safe to assume I can’t retro-inject mocked services to the module I’m testing. So then what can I inject and what are the use cases?

您可以在任何地方(通常在每个和它之前)运行angular.mock.inject.模拟服务应仅在模块或匿名模块初始化函数中配置(如在您的示例中使用$provide和$window),并且通常在您自己的模块(即“security.service”)之后,以覆盖实际服务通过在喷射器中更换它们.一旦运行了inject(),就无法使用mock来回溯替换服务.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读