(这里有一个相关问题:
Jasmine test does not see AngularJS module)
我只是想测试一个服务没有bootstrapping Angular。
我看看一些例子和教程,但我不会去任何地方。
我只有三个文件:
> myService.js:其中我定义了一个AngularJS服务
> test_myService.js:其中我为服务定义了一个Jasmine测试。
> specRunner.html:具有正常茉莉花配置的HTML文件
并在其中我导入前两个其他文件和Jasmine,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); }) }) });
问题是,在上面的示例中没有调用实例化服务的工厂方法(只创建模块不实例化服务)。
为了实例化服务,必须使用定义了服务的模块调用angular.injector。然后,我们可以询问新的注入器对象的服务,它只有当服务最终实例化时。
这样的东西工作:
describe('myService test',function(){ var $injector = angular.injector([ 'myModule' ]); var myService = $injector.get( 'myService' ); expect( myService.one ).toEqual(1); }) }) });
describe('myService test',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‘。
当这样做时,我们必须意识到,’inject’函数不在标准的angularjs包中,而是在ngMock模块中,并且它只适用于茉莉花。
describe('myService test',function(){ beforeEach(module('myModule')); it('returns 1',inject(function(myService){ //parameter name = service name expect( myService.one ).toEqual(1); })) }) });