0

I guess I miss something. Have spent some time trying to understand why my test is not working.

The code.

angular.module('services')
    .factory('UserPreferencesService', ['$resource', function ($resource)
    {
        return $resource('/rest/user-preferences/:id', {},
        { getById: { method: "GET", params: { id:'@id'}} });

    }
]);

The test:

it('should get by Id', function() {
    //given
    var preferences = {language: "en"};

    httpBackend.whenGET('/rest/user-preferences/1').respond(preferences);

    //when
    service.getById( {id:1} ).$promise.then(function(result) {

        console.log("successssssssssssssssssssssssssssssssssssss");

     //then
     expect(result).toEqual(preferences);
    }, function() {
        console.log("something wrong");
    })
});

It never triggers: "successssssssssssssssssssssssssssssssssssss".

What did I miss?

Josep
  • 12,926
  • 2
  • 42
  • 45
ses
  • 13,174
  • 31
  • 123
  • 226

2 Answers2

4

There were some things wrong and other things missing in your code.

The main problem was that you were not calling the flush() function that emulates the response from the server, so the $promise was never resolved. Also, bear in mind that when the promise gets resolved, the response that you get it's a promise, meaning that this: expect(result).toEqual(preferences); won't work, but this: expect(result.lang).toEqual(preferences.lang); will.

Here you have a fixed version of your code:

The service:

angular.module('services',['ngResource'])
    .factory('UserPreferencesService', ['$resource', function ($resource)
    {
      return $resource('/rest/user-preferences/:id', {},
        { getById: { method: "GET", params: { id:'@id'}} });
    }
]);

The Test:

describe('My Suite', function () {
  var httpBackend, service; 
  beforeEach(module('services'));

  beforeEach(inject(function (_$httpBackend_, UserPreferencesService) {
      httpBackend = _$httpBackend_;
      service = UserPreferencesService;
  }));

  describe('My Test', function () {
      it('should get by Id', function() {
        var preferences = {language: "en"};
        var result = {};

        httpBackend.whenGET('/rest/user-preferences/1').respond(preferences);

        service.getById({id:1}).$promise.then(function(result_) {
          result = result_;
        });

        expect(result.language).not.toEqual(preferences.language);

        httpBackend.flush();

        expect(result.language).toEqual(preferences.language);
    });
  });
});

Working Example

Josep
  • 12,926
  • 2
  • 42
  • 45
  • Is there a possibility that result is not yet processed after .flush() in very last expect(result.language)... ? But empty {} object, since promise is not yet processed. – ses Oct 17 '14 at 17:43
  • @ses not in this case, unless you did something like this: `service.getById({id:1}).$promise.then(function(result_) { $timeout(function(){result = result_;}); });` Example: http://plnkr.co/edit/L4sVkGQMiRmxqP6lED8J?p=preview – Josep Oct 17 '14 at 18:17
0

I would like to add to this that I had the same issue, but was using the callback, as follows:

 httpBackend.whenGET('/rest/user-preferences/1').respond(function(method, url, data) {
                //do something with method, url, data...
                return 200;
            });

It never got hit until i replaced return 200, by return [200]. Apparently it needs an array to return.

I feel this info could be made more explicit in the documentation.

Ralf Stubner
  • 26,263
  • 3
  • 40
  • 75