Øyvind Hellenes
Øyvind Hellenes

Reputation: 517

Testing with $httpBackend in services

I've just started to dig into some testing with AngularJS, but I can't say I understand it completely yet. I want to test the REST API methods in my factory, but I'm just getting errors. Not sure what I'm doing wrong. Can anyone help me?

My factory:

'use strict';

angular.module('corsaneApp')
  .factory('resourceService', ['$http', '$log', '$resource', '$sce', 'listService', 'global', 'config',
    function($http, $log, $resource, $sce, listService, global, config) {

      var search = null;

      return {
        post: function(name, url, type, res) {
          var prefix = 'http';
          if (url.substr(0, prefix.length) !== prefix) {
            url = prefix + '://' + url;
            $log.info('NewUrl ' + url);
          }
          // Post resource
          $http.post(config.apiBaseUrl + 'resources?name=' + name + '&url=' + url + '&format=' + type).success(function(data) {
            var bool = global.toPlaylist();
            $log.info("Data" + data.url + data.name + 'Bool' + bool.value);
            alert('Success');
            if (bool.value) {
              var playlist = global.setList();
              listService.addListElement(data, playlist.value);
              res.push(data);
            };
          }).error(function(error, data, status, config) {
            $log.info("It doesnt work!" + data + config);
          });

        },
        get: function() {
          return search;
        },
        search: function(term) {
          var tmp = $resource(config.apiBaseUrl + 'resources/' + term, {
            id: '@id'
          }, {});
          search = tmp.query();
          return tmp.query();
        },
        show: function(item) {

          // Assign a resource to selected variable.
          global.setResource(item);


        }
      }
    }
  ]);

Test file:

'use strict';

describe('Service: resource', function() {

  // load the service's module
  beforeEach(module('corsaneApp'));

  // instantiate service
  var $httpBackend;
  var conf;
  var getResource;
  var tmp;
  var resource;

  beforeEach(inject(function($rootScope, _$httpBackend_, $http, config, resourceService) {
    conf = config;
    $httpBackend = _$httpBackend_;
    resource = resourceService;

  }));

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

  it('should return a list of resources', function() {
    $httpBackend.expectGET(conf.apiBaseUrl + 'resources/queen').respond({
      "id": 1,
      "url": "https://en.wikipedia.org/wiki/Elizabeth",
      "text": "no written-explanationobject",
      "name": "queen 1"
    }, {
      "id": 2,
      "url": "https://en.wikipedia.org/wiki/Elizabeth_II",
      "text": "no written-explanationobject",
      "name": "queen 2"
    });
    tmp = resource.search('queen');
    tmp.$promise.then(function(data) {
      getResource = data;
    })
    $httpBackend.flush();

    expect(getResource[0].id).toBe(1);
  });

});

Error message:

Chrome 35.0.1916 (Mac OS X 10.9.3) Service: resource should return a list of resources FAILED
    Error: Unexpected request: GET http://localhost:8888/Corsane/web/app_dev.php/api/resources/queen
    No more request expected
        at $httpBackend (/Users/oyvindhellenes/Documents/Corsane/app/bower_components/angular-mocks/angular-mocks.js:1177:9)
        at sendReq (/Users/oyvindhellenes/Documents/Corsane/app/bower_components/angular/angular.js:8263:9)
        at $http.serverRequest (/Users/oyvindhellenes/Documents/Corsane/app/bower_components/angular/angular.js:7995:16)
        at wrappedCallback (/Users/oyvindhellenes/Documents/Corsane/app/bower_components/angular/angular.js:11485:81)
        at wrappedCallback (/Users/oyvindhellenes/Documents/Corsane/app/bower_components/angular/angular.js:11485:81)
        at /Users/oyvindhellenes/Documents/Corsane/app/bower_components/angular/angular.js:11571:26
        at Scope.$eval (/Users/oyvindhellenes/Documents/Corsane/app/bower_components/angular/angular.js:12595:28)
        at Scope.$digest (/Users/oyvindhellenes/Documents/Corsane/app/bower_components/angular/angular.js:12407:31)
        at Function.$httpBackend.flush (/Users/oyvindhellenes/Documents/Corsane/app/bower_components/angular-mocks/angular-mocks.js:1435:16)
        at null.<anonymous> (/Users/oyvindhellenes/Documents/Corsane/test/spec/services/resource.js:43:18)
    Error: Unflushed requests: 1
        at Function.$httpBackend.verifyNoOutstandingRequest (/Users/oyvindhellenes/Documents/Corsane/app/bower_components/angular-mocks/angular-mocks.js:1489:13)
        at null.<anonymous> (/Users/oyvindhellenes/Documents/Corsane/test/spec/services/resource.js:24:18)
Chrome 35.0.1916 (Mac OS X 10.9.3): Executed 1 of 1 Chrome 35.0.1916 (Mac OS X 10.9.3): Executed 1 of 1 (1 FAILED) ERROR (0.053 secs / 0.051 secs)
Warning: Task "karma:unit" failed. Use --force to continue.

Aborted due to warnings.

Upvotes: 3

Views: 1428

Answers (1)

ne4istb
ne4istb

Reputation: 672

It seams the problem is that you call request twice in search function.

You use $httpBackend.verifyNoOutstandingRequest. It checks if number of requests is not more then you expect in test.

To fix it you could try next changes:

 search: function(term) {
          var tmp = $resource(config.apiBaseUrl + 'resources/' + term, {
            id: '@id'
          }, {});
          search = tmp.query();
          return search;
        },

Sorry, i have not possibility to check it yourself now, but it should resolve this problem

Upvotes: 4

Related Questions