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

Georgii Oleinikov

I have myService that uses myOtherService, which makes a remote call, returning promise:

angular.module('app.myService', ['app.myOtherService'])
  .factory('myService', [
    myOtherService,
    function(myOtherService) {
      function makeRemoteCall() {
        return myOtherService.makeRemoteCallReturningPromise();
      }

      return {
        makeRemoteCall: makeRemoteCall
      };      
    }
  ])

To make a unit test for myService I need to mock myOtherService, such that its makeRemoteCallReturningPromise method returns a promise. This is how I do it:

describe('Testing remote call returning promise', function() {
  var myService;
  var myOtherServiceMock = {};

  beforeEach(module('app.myService'));

  // I have to inject mock when calling module(),
  // and module() should come before any inject()
  beforeEach(module(function ($provide) {
    $provide.value('myOtherService', myOtherServiceMock);
  }));

  // However, in order to properly construct my mock
  // I need $q, which can give me a promise
  beforeEach(inject(function(_myService_, $q){
    myService = _myService_;
    myOtherServiceMock = {
      makeRemoteCallReturningPromise: function() {
        var deferred = $q.defer();

        deferred.resolve('Remote call result');

        return deferred.promise;
      }    
    };
  }

  // Here the value of myOtherServiceMock is not
  // updated, and it is still {}
  it('can do remote call', inject(function() {
    myService.makeRemoteCall() // Error: makeRemoteCall() is not defined on {}
      .then(function() {
        console.log('Success');
      });    
  }));  

As you can see from the above, the definition of my mock depends on $q, which I have to load using inject(). Furthermore, injecting the mock should be happening in module(), which should be coming before inject(). However, the value for the mock is not updated once I change it.

What is the proper way to do this?

dnc253

I'm not sure why the way you did it doesn't work, but I usually do it with the spyOn function. Something like this:

describe('Testing remote call returning promise', function() {
  var myService;

  beforeEach(module('app.myService'));

  beforeEach(inject( function(_myService_, myOtherService, $q){
    myService = _myService_;
    spyOn(myOtherService, "makeRemoteCallReturningPromise").and.callFake(function() {
        var deferred = $q.defer();
        deferred.resolve('Remote call result');
        return deferred.promise;
    });
  }

  it('can do remote call', inject(function() {
    myService.makeRemoteCall()
      .then(function() {
        console.log('Success');
      });    
  }));

Also remember that you will need to make a $digest call for the then function to be called. See the Testing section of the $q documentation.

------EDIT------

After looking closer at what you're doing, I think I see the problem in your code. In the beforeEach, you're setting myOtherServiceMock to a whole new object. The $provide will never see this reference. You just need to update the existing reference:

beforeEach(inject( function(_myService_, $q){
    myService = _myService_;
    myOtherServiceMock.makeRemoteCallReturningPromise = function() {
        var deferred = $q.defer();
        deferred.resolve('Remote call result');
        return deferred.promise;   
    };
  }

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Unit test service that returns promise Angularjs Jasmine

From Dev

Unit test service that returns promise Angularjs Jasmine

From Dev

How do I mock $http in AngularJS service Jasmine test?

From Dev

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

From Dev

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

From Dev

AngularJS Controller As Jasmine test with mock service with promise

From Dev

How to test with Jasmine an AngularJS controller that calls service method that returns promise

From Dev

Angular and Jasmine: how to mock a service that returns a promise

From Dev

How can I test what an AngularJS promise returns using Jasmine?

From Dev

How can I test what an AngularJS promise returns using Jasmine?

From Dev

How do I unit test a service-dependent function in Jasmine?

From Dev

How to unit test (using Jasmine) a function in a controller which calls a factory service which returns a promise

From Dev

how to mock $window to unit test AngularJS service?

From Dev

How do I resolve a promise in an AngularJS unit test

From Dev

How do I unit test an AngularJS controller that relies on a promise?

From Dev

mock angularjs service for unit testing using jasmine

From Dev

mock angular service/promise in a karma/jasmine test

From Dev

angularjs unit test karma with jasmine mock dilemma

From Dev

How to test that my service returns data with jasmine and angularjs

From Dev

How to mock AngularJS $resource with $promise.then in jasmine

From Dev

How to mock AngularJS $resource with $promise.then in jasmine

From Dev

How do I mock a factory that returns a promise in angularJs 1.x

From Dev

How Can I Test a .catch Promise Return in AngularJS using Jasmine?

From Dev

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

From Dev

How do I mock an Angular service using jasmine?

From Dev

How to mock Angular $q service in Jasmine test?

From Dev

How do I unit test a init() function with Jasmine?

From Dev

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

From Dev

Jasmine unit testing angular service that returns promise doesn't resolve

Related Related

  1. 1

    Unit test service that returns promise Angularjs Jasmine

  2. 2

    Unit test service that returns promise Angularjs Jasmine

  3. 3

    How do I mock $http in AngularJS service Jasmine test?

  4. 4

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

  5. 5

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

  6. 6

    AngularJS Controller As Jasmine test with mock service with promise

  7. 7

    How to test with Jasmine an AngularJS controller that calls service method that returns promise

  8. 8

    Angular and Jasmine: how to mock a service that returns a promise

  9. 9

    How can I test what an AngularJS promise returns using Jasmine?

  10. 10

    How can I test what an AngularJS promise returns using Jasmine?

  11. 11

    How do I unit test a service-dependent function in Jasmine?

  12. 12

    How to unit test (using Jasmine) a function in a controller which calls a factory service which returns a promise

  13. 13

    how to mock $window to unit test AngularJS service?

  14. 14

    How do I resolve a promise in an AngularJS unit test

  15. 15

    How do I unit test an AngularJS controller that relies on a promise?

  16. 16

    mock angularjs service for unit testing using jasmine

  17. 17

    mock angular service/promise in a karma/jasmine test

  18. 18

    angularjs unit test karma with jasmine mock dilemma

  19. 19

    How to test that my service returns data with jasmine and angularjs

  20. 20

    How to mock AngularJS $resource with $promise.then in jasmine

  21. 21

    How to mock AngularJS $resource with $promise.then in jasmine

  22. 22

    How do I mock a factory that returns a promise in angularJs 1.x

  23. 23

    How Can I Test a .catch Promise Return in AngularJS using Jasmine?

  24. 24

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

  25. 25

    How do I mock an Angular service using jasmine?

  26. 26

    How to mock Angular $q service in Jasmine test?

  27. 27

    How do I unit test a init() function with Jasmine?

  28. 28

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

  29. 29

    Jasmine unit testing angular service that returns promise doesn't resolve

HotTag

Archive