简体   繁体   中英

Jasmine spy not being called

I have created an angular service which I am testing without any issue, I then started trying to inject a dependency into the tests when I started having an issue.

I want to make sure that a function in the dependency has been called but it's coming back undefined.

Here's my service:

angular.module('enigmaApp.services', [])
    .factory('auth', function($window, $http, SS){
        var auth = {};

        auth.register = function(user){
            return $http.post('/register', user)
            .success(function(data){
                if(data.token){
                    SS.setObj('appToken', data.token);
                }
            });
        };

        return auth;
    });

My test:

describe('Auth Service Tests', function () {
  var $httpBackend, auth, defer, registerReqHandler, setObjSpy, SS, SSMock, user;

  beforeEach(module('enigmaApp'));

  beforeEach(function () {    
    // Create spies
    setObjSpy = jasmine.createSpy('setObj');

    SSMock = {
      setObj: setObjSpy
    }

    SS = SSMock;

    module(function ($provide) {
      $provide.value('SS', SSMock);
    });
  });

  beforeEach(inject(function (_$httpBackend_, $injector, $q) {
    $httpBackend = _$httpBackend_; 
    defer = $q.defer();
    registerReqHandler = $httpBackend.when('POST', '/register').respond(defer.promise);
    auth = $injector.get('auth');
  }));

  afterEach(function () {
    $httpBackend.flush();
    $httpBackend.verifyNoOutstandingExpectation();
    $httpBackend.verifyNoOutstandingRequest();
  });

  describe('auth.register(user)', function () {
    beforeEach(function () {
      user = {
        email: 'bwayne@wayneenterprise.com',
        first_name: 'Bruce',
        last_name: 'Wyane',
        password: 'password123'
      };
    });

    it('should call SS.setObj on successful registration', function () {
      $httpBackend.expectPOST('/register').respond({ token: 'fakeToken' });
      auth.register(user);
      expect(SS.setObj).toHaveBeenCalled();
    });
  });

When I run the tests I get a failed test that says "Expected spy setObj to have been called." Any idea on what I'm doing wrong here? I thought I set up a mock for SS.setObj and provided it to the module,

One problem you have is that it seems you aren't actually returning your auth object in your factory:

angular.module('enigmaApp.services', [])
.factory('auth', function($window, $http, SS){
    var auth = {};

    auth.register = function(user){
        return $http.post('/register', user)
        .success(function(data){
            if(data.token){
                SS.setObj('appToken', data.token);
            }
        });
    };


    // need to return auth here...
    return auth;
});

update

Move your flush call into your it block

it('should call SS.setObj on successful registration', function () {

  $httpBackend
    .expectPOST('/register')
    .respond({ token: 'fakeToken' });

  auth.register(user);
  $httpBackend.flush();

  expect(SS.setObj).toHaveBeenCalled();
});

afterEach blocks are for clean up. Jasmine assumes your test is over by that point so your flush() call won't have any effect.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM