angularjsjasminetddangularjs-ng-resource

How to test $resource calls if it contains specific headers on making http request?


I have this following factory.

services.factory('Api', ['$resource', function ($resource) {

        return $resource(urlPath, {
            'action': 'get',
            'entity': 'Entity'
        }, {
          MakePost: {
            method: "POST",
            isArray: false,
            headers: {'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'},
            transformRequest: function(obj) {
              var str = [];

              for (var p in obj) {
                str.push(encodeURIComponent(p) + '=' + encodeURIComponent(obj[p]));
              }

              return str.join("&");
            }
          }
        }
      );
    }]);

Now, i would like to test, when calling Api.MakePost({},{data: {}}, function () {}) the correct header data i.e in this case 'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8' is set correctly. Is there away to test this scenario in angularjs, using $httpBackend, Jasmine and spies?


Solution

  • This can be tested in two different ways, with unit and functional tests.

    When compared with $http, $resource contains more moving parts, and it makes sense to stub it - at least for some tests.

    beforeEach(module('app'))
    ...
    describe('$resource is stubbed in this block', () => {
      var resourceObjStub;
      var resourceFactoryStub;
    
      beforeEach(() => {
        resourceObjStub = jasmine.createSpyObj(['MakePost']);
        resourceFactoryStub = jasmine.createSpy().and.returnValue(resourceObjStub);
    
        module({ $resource: resourceFactoryStub });
      });
    
      it('...', inject((Api) => {
        expect(resourceFactoryStub).toHaveBeenCalledWith(
          ...
          {...},
          { MakePost: {
            headers: {...},
            transformRequest: jasmine.any(Function),
            ...
          } }
        );
        expect(Api).toBe(resourceObjStub);
      });
    });
    

    Then provided $resource arguments can be tested more thoroughly, e.g. transformRequest method can be reached with resourceFactoryStub.calls.first()[2].transformRequest and tested directly.

    Or the whole thing can be tested in another test with $httpBackend and real $resource.