Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jasmine/AngularJS: Inject dependent service to service in unit test?

I have angular modules:

var app = angular.module("SearchUI",[]);

in it, I have a service "configService", that maintains bunch of config params:

app.provider("configService",function(){
  //stuff here
})

I have ran the jasmine unit tests in configService fineL

describe('configService',function(){

var configService,$httpBackend;


    beforeEach(module('SearchUI'));
    beforeEach(inject(function(_configService_,$injector){
        configService = _configService_;    
        $httpBackend = $injector.get("$httpBackend");

    }));

    it('should have default values for configService', function(){
        expect(configService.getDefaultSearch()).toEqual(['abstract','title','keyword','keywordplus'
    ]);
    });

//other stuff

all tests pass fine.

however, I am not understanding how to maintain that injection in another service:

i.e in my application:

app.service("SearchService",function($http,$log,configService,$q){
    //stuff
    search_params = configService.getDefaultSearch();

})

my spec:

describe('SearchService',function(){
    var searchService,configService;

    beforeEach(module('SearchUI'));
    beforeEach(inject(function(_configService_,_SearchService_){
        configService = _configService_;    
        searchService = _SearchService_;

    }));


    it('SearchService should return results', function(){
        var waiting = searchService.SimpleSearch("card","wos",0);


//other stuff

the spec fails because in simplesearch function requires this:

search_params = configService.getDefaultSearch(); //get the default search parameters       

my question is, how do I inject the required service in to the ANOTHER service?

like image 887
nate Avatar asked Apr 18 '15 00:04

nate


People also ask

How do I inject a service in AngularJS?

There is one more way to inject dependencies in AngularJS: by using the $inject service. In doing so, we manually inject the dependencies. We can inject $scope object dependencies using the $inject service as shown in the listing below: function ProductController($scope){ $scope.

Which function is used to inject a service into a test function?

To test a service, you set the providers metadata property with an array of the services that you'll test or mock. content_copy let service: ValueService; beforeEach(() => { TestBed. configureTestingModule({ providers: [ValueService] }); }); Then inject it inside a test by calling TestBed.

How do you inject a service in component angular test?

We can inject the service as following. empService = TestBed. inject(EmployeeService); In our example we will inject a simple service as well as a service with HttpClient dependency.

What is injection dependency in AngularJS?

Dependency Injection is a software design in which components are given their dependencies instead of hard coding them within the component. It relieves a component from locating the dependency and makes dependencies configurable. It also helps in making components reusable, maintainable and testable.


1 Answers

Services are simply JavaScript classes and you can create an instance of them without using angular's inject mechanism to facilitate your dependency injection. Instead you can simply create a new instance of the class yourself while supplying the parameters which are required.

Currently you are creating your service via an inline function:

app.service("SearchService",function($http,$log,configService,$q){...

Instead of that by making a small adjustment which will separate out the declaration of the service from its injection into the angular module. Doing so will allow you to gain access from your test to the service class.

function SearchService($http, configService){...

app.service("SearchService", SearchService);

From your test you suite you can prepare your injectables in your beforeEach preprocessor:

describe('configService',function(){

    var configService, httpBackend;
    beforeEach(module('SearchUI'));
    beforeEach(inject(function($httpBackend){
        httpBackend = "$httpBackend";
        configService = jasmine.createSpyObj('configService', ['getDefaultSearch']);
    }));

    /* helper method that I create to only have one place where the service is created 
    If I add a new param/dependency then I only have to change the construction once */
    function createService(){
        return new SearchService(httpBackend, configService);
    }
});

The main reason for taking this approach to testing (controlling the dependency injection manually rather than relying on angular's implementation) is to have full control and to truly isolate the item I am trying to test.

like image 141
Brocco Avatar answered Nov 03 '22 01:11

Brocco