一尘不染

如何使用Jasmine测试AngularJS服务?

angularjs

我只想在不引导Angular的情况下测试服务。

我看了一些例子和教程,但是我什么也不会去。

我只有三个文件:

  • myService.js:在这里定义AngularJS服务

  • test_myService.js:在这里定义服务的Jasmine测试。

  • specRunner.html:一个具有常规茉莉花配置的HTML文件,在其中导入了前两个其他文件以及茉莉花,Angularjs和angular-mocks.js。

这是该服务的代码(在未测试时可以正常工作):

var myModule = angular.module('myModule', []);

myModule.factory('myService', function(){

    var serviceImplementation   = {};
    serviceImplementation.one   = 1;
    serviceImplementation.two   = 2;
    serviceImplementation.three = 3;

    return serviceImplementation

});

当我尝试单独测试服务时,我应该能够访问它并检查其方法。我的问题是:如何在不引导AngularJS的情况下在测试中注入服务?

例如,如何使用Jasmine测试服务方法返回的值,如下所示:

describe('myService test', function(){
    describe('when I call myService.one', function(){
        it('returns 1', function(){
            myModule = angular.module('myModule');
                    //something is missing here..
            expect( myService.one ).toEqual(1);
        })

    })

});

阅读 194

收藏
2020-07-04

共1个答案

一尘不染

问题在于,在上面的示例中未调用实例化服务的factory方法(仅创建模块不会实例化服务)。

为了实例化服务,必须在定义我们服务的模块中调用angular.injector。然后,我们可以向新的注入器对象请求服务,并且只有在最终实例化服务时才向它请求。

像这样的作品:

describe('myService test', function(){
    describe('when I call myService.one', function(){
        it('returns 1', function(){
            var $injector = angular.injector([ 'myModule' ]);
            var myService = $injector.get( 'myService' );
            expect( myService.one ).toEqual(1);
        })

    })

});

另一种方法是使用’ invoke ‘ 将服务传递给函数:

describe('myService test', function(){
    describe('when I call myService.one', function(){
        it('returns 1', function(){

            myTestFunction = function(aService){
                expect( aService.one ).toEqual(1);
            }

            //we only need the following line if the name of the 
            //parameter in myTestFunction is not 'myService' or if
            //the code is going to be minify.
            myTestFunction.$inject = [ 'myService' ];

            var myInjector = angular.injector([ 'myModule' ]);
            myInjector.invoke( myTestFunction );
        })

    })

});

最后,“正确”的方法是在“ beforeEach ”茉莉花块中使用“
inject
”和“
module
。在执行此操作时,我们必须意识到“注入”功能不是在标准的angularjs软件包中,而是在ngMock模块中,并且它只能与茉莉一起使用。

describe('myService test', function(){
    describe('when I call myService.one', function(){
        beforeEach(module('myModule'));
        it('returns 1', inject(function(myService){ //parameter name = service name

            expect( myService.one ).toEqual(1);

        }))

    })

});
2020-07-04