AngularJS override (mock) services for unit test

Rn2dy

The scenario is very simple, I am trying to test a service A, which depends on service B, so I decided to mock service B by overriding it before I inject service A. However, I am also testing service B which is no longer valid since it is overridden. Any idea on how to avoid this?

Application code.

angular.module('MyApp.services')
  .factory('serviceB', function(){
    return {
      greeting: function(){ return 'hello'; }
    }
  })
  .factory('serviceA', ['serviceB', function(serviceB){
    return {
      greeting: function(){
        return 'I say: ' + serviceB.greeting();
      }
  });

Unit Test:

describe('My app services', function(){

  beforeEach(module('MyApp.services'));

  describe('service A', function(){
      // mock service B
    angular.module('MyApp.services').factory('serviceB', function(){
      return { greeting: function(){ return 'mocked B'; } }
    });

    var serviceA;

    inject(function(_serviceA_){
      serviceA = _serviceA_;
    });

    it('should work', function(){
      var words = serviceA.greeting();
      expect(words).toBe('I say: mocked B');          
    });
  });

  describe('service B'. function(){
    var serviceB;

    inject(function(_serviceB_){
      serviceB = _serviceB_;
    });

    it('should work', function(){
      var words = serviceB.greeting();
      expect(words).toBe('hello');
    });
  });
});
Andyrooger

Your service injection should probably be either in a beforeEach or as part of the tests, otherwise I think they will happen before the tests begin or not at all, e.g.

beforeEach(inject(function(_serviceA_){
  serviceA = _serviceA_;
}));

or

it('should work', inject(function(serviceA){
    var words = serviceA.greeting();
    expect(words).toBe('I say: mocked B');          
}));

To solve the problem you are actually asking about, I suggest you do one of two things:

  1. Override the service in the injector rather than the module

    beforeEach(module(function($provide){
      $provide.value('serviceB', {
        greeting: function(){ return 'mocked B'; }
      });
    }));
    

    See plunker.

  2. Use a separate module that can be added when needed to override serviceB

    Somewhere (that only needs to be called once), put the definition of your new module containing your mock version of serviceB

    angular.module('MyApp.services.mock', [])
      .factory('serviceB', function(){
        return { greeting: function(){ return 'mocked B'; } }
      });
    

    then where you currently alter the service in your module under test, use the following to load your module with the mock on top.

    beforeEach(module('MyApp.services.mock'));
    

    See plunker

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Java

How do I mock a service that returns promise in AngularJS Jasmine unit test?

From Dev

How do I mock the result of a promise in an AngularJS unit test?

From Dev

Correct way to mock an AngularJS Service in a unit test?

From Dev

AngularJS override (mock) services for unit test

From Dev

How to mock $window.location.replace in AngularJS unit test?

From Dev

angularjs unit test karma with jasmine mock dilemma

From Dev

Unit test of controller angularjs

From Dev

Unit test angularjs controller

From Dev

how to mock $window to unit test AngularJS service?

From Dev

Is there a way in AngularJs to test controllers with Services and only mock\stub things like $http?

From Dev

How to quickly mock services in spring unit tests?

From Dev

Unit tests should mock all external services?

From Dev

AngularJS - Unit Test with $timeout

From Dev

Angularjs: mock location.path() with spyOn for a unit test

From Dev

AngularJs unit test 'this'

From Dev

How to mock springSecurityService in an unit test

From Dev

How to mock this unit test in Python?

From Dev

Mock/Stub a RuntimeException in unit test

From Dev

Spock Mock not working for unit test

From Dev

Mock IMemoryCache in unit test

From Dev

How do I mock the result of a promise in an AngularJS unit test?

From Dev

Angularjs Unit Test for Service

From Dev

Unit Test Azure Cloud Services

From Dev

Is there a way in AngularJs to test controllers with Services and only mock\stub things like $http?

From Dev

How to mock an event like 'keypress' or 'keydown' in an AngularJS unit test?

From Dev

Angularjs: mock location.path() with spyOn for a unit test

From Dev

Unit test a void method with Mock?

From Dev

AngularJS + Jasmine mock unit test $http factory of POST method

From Dev

Spring security, test MVC and mock services

Related Related

  1. 1

    How do I mock a service that returns promise in AngularJS Jasmine unit test?

  2. 2

    How do I mock the result of a promise in an AngularJS unit test?

  3. 3

    Correct way to mock an AngularJS Service in a unit test?

  4. 4

    AngularJS override (mock) services for unit test

  5. 5

    How to mock $window.location.replace in AngularJS unit test?

  6. 6

    angularjs unit test karma with jasmine mock dilemma

  7. 7

    Unit test of controller angularjs

  8. 8

    Unit test angularjs controller

  9. 9

    how to mock $window to unit test AngularJS service?

  10. 10

    Is there a way in AngularJs to test controllers with Services and only mock\stub things like $http?

  11. 11

    How to quickly mock services in spring unit tests?

  12. 12

    Unit tests should mock all external services?

  13. 13

    AngularJS - Unit Test with $timeout

  14. 14

    Angularjs: mock location.path() with spyOn for a unit test

  15. 15

    AngularJs unit test 'this'

  16. 16

    How to mock springSecurityService in an unit test

  17. 17

    How to mock this unit test in Python?

  18. 18

    Mock/Stub a RuntimeException in unit test

  19. 19

    Spock Mock not working for unit test

  20. 20

    Mock IMemoryCache in unit test

  21. 21

    How do I mock the result of a promise in an AngularJS unit test?

  22. 22

    Angularjs Unit Test for Service

  23. 23

    Unit Test Azure Cloud Services

  24. 24

    Is there a way in AngularJs to test controllers with Services and only mock\stub things like $http?

  25. 25

    How to mock an event like 'keypress' or 'keydown' in an AngularJS unit test?

  26. 26

    Angularjs: mock location.path() with spyOn for a unit test

  27. 27

    Unit test a void method with Mock?

  28. 28

    AngularJS + Jasmine mock unit test $http factory of POST method

  29. 29

    Spring security, test MVC and mock services

HotTag

Archive