Michel
Michel

Reputation: 23615

Test an Angular service with real and mocked dependencies

I have a service for which I need to use 2 real injected objects and 1 mock. I've read (and used in another class) this post Injecting a mock into an AngularJS service how to mock a service dependency, but I can't figure out how to create my service in the unit test when I want the appConfig and the sessionStorage mocked, and to use the real $resource

this is my service

.factory('accountService',
    [
        'appConfig',
        'sessionStorage',
        '$resource',
        function accountService_init (appConfig, sessionStorage, $resource){

            // some account methods are done on a web endpoint
            var webauthendpoint = appConfig.locations.authEndPoint + ':method';

            // Others are done on the API endpoint
            var Account = $resource(appConfig.locations.api.account, {
                method: '@method'
            });

            //removed code

            return Account;
        }
    ]
);

So I've seen code where all the dependencies are mocked (in the beforeEach, with the $provide.value and then after that the object can be injected in the expect like this:

it('should return value from mock dependency', inject(function (myService) {
      expect(myService.useDependency()).toBe('mockReturnValue');
  }));

I've seen (and used ) also the example of a service questionsPersistenceService which is dependant of userPrefilledPersistService:

beforeEach(inject(function (_questionsPersistenceService_, _userPrefilledPersistService_) {
        questionsPersistenceService = _questionsPersistenceService_;
        userPrefilledPersistService = _userPrefilledPersistService_;
    }));

But how to combine??

EDIT, because my question has been identified as a possible duplicate of another question.

@Estus: possible duplicate?? That post is about mocking a service in a directive. In my post I've stated that I DO know how to do that, but that my problem is about how to combine injecting live dependencies and mocking dependencies, in the same test

Upvotes: 0

Views: 644

Answers (1)

Anke Wenz
Anke Wenz

Reputation: 415

you can just combine it.
but it's possible too, that you inject all your dependencies like this:

var dep1, dep2, dep3;

beforeEach(inject(function(_dependency1_, _dependecy2_, _dependecy3_){
   dep1 = _dependency1_;
   spyOn(dep1, 'methodYouUseLikeReal').and.callThrough();

   dep2 = _dependecy2_;
   spyOn(dep2, 'otherMethodYouUseTheOriginalCode').and.callThrough();

   dep3 = _dependecy3_;
   spyOn(dep3, 'methodYouLikeToMock').and.respond(
       function() {
            return 'someMockValueOrFunctionality';
       }
   );
}));

and then on your testcase:

it('returns true expected value for dep1 and dep2 and someMockValueOrFunctionality for dep3', function (){
    var result1 = dep1.methodYouUseLikeReal();
    expect(dep1.methodYouUseLikeReal).toHaveBeenCalled();
    expect(result1).toBe('real expected result');

    var result2 = dep2.otherMethodYouUseTheOriginalCode(param);
    expect(dep2.otherMethodYouUseTheOriginalCode).toHaveBeenCalledWith(param);
    expect(dep2.otherMethodYouUseTheOriginalCode).toBe('real result');

    var result3 = dep3.methodYouLikeToMock();
    expect(dep3.methodYouLikeToMock).toHaveBeenCalled();
    expect(result3).toBe('someMockValueOrFunctionality');
});

I hope this will help you.

Upvotes: 2

Related Questions