jeudi 19 novembre 2015

Karma and $resource

I am new with Karma and am trying to set up a few unit tests but I'm meeting some issues.

First, here is my apiService.js file where I define my factories using $resource :

'use strict';

angular.module('balrogApp.services', ['balrogApp.config', 'ngResource'])
  .factory('Requests', ['$resource', 'balrogConfig', function($resource, balrogConfig) {
    return $resource(balrogConfig.backend + '/requests/:id', {id: '@id'});
  }])
  .factory('Projects', ['$resource', 'balrogConfig', function($resource, balrogConfig) {
    return $resource(balrogConfig.backend + '/projects/:id', {id: '@id'}, {'update': { method:'PUT' }});
  }])
  /*  Other factories are there */
  .factory('CostEstimations', ['$resource', 'balrogConfig', function($resource, balrogConfig) {
    return $resource(balrogConfig.backend + '/costestimations/:id', {id: '@id'});
  }]);

A config.js file where I define a constant to use for the API url :

'use strict';

angular.module('balrogApp.config', [])
  .constant('balrogConfig', {
    'backend': 'http://ift.tt/1H8fCKO'
  });

requests/requests.js file, the controller I'm testing :

'use strict';

angular.module('balrogApp.requests', [
  /* Dependancies */
])
  // Routes configuration
  .config(['$routeProvider', function($routeProvider) {
    $routeProvider
      /* Routes configuration using .when(...) */
  }])
  .controller('requestsController', function(Requests, Users, Projects, RequestsComments, CostEstimations,
                                             Regions, growl, $route, $rootScope, $scope, $location) {
    this.$route = $route;

    /* ... */

    this.changeView = function(viewPath) {
      $location.path(viewPath);
    };

    this.usersList = Users.query();
    this.requestsList = Requests.query();
    this.projectsList = Projects.query();
    this.requestsCommentsList = RequestsComments.query();
    this.costEstimationsList = CostEstimations.query();
    this.regionsList = Regions.query();
  });

tests/requests.js file, my test file :

describe('Requests controller test', function() {
  beforeEach(module('balrogApp.requests'));

  var ctrl, scope;

  var testData = [
    {id: 1, project: {id: 1, title: 'Balrog'}, description: 'Some description'},
    {id: 2, project: {id: 2, title: 'Catax'}, description: 'Another description'}
  ];

  beforeEach(inject(function($rootScope, $controller, _$httpBackend_) {
    $httpBackend = _$httpBackend_;

    $httpBackend.expectGET('/users').respond(testData);
    $httpBackend.expectGET('/requests').respond(testData);
    $httpBackend.expectGET('/projects').respond(testData);
    $httpBackend.expectGET('/requestcomments').respond(testData);
    $httpBackend.expectGET('/costestimations').respond(testData);
    $httpBackend.expectGET('/regions').respond(testData);

    scope = $rootScope.$new();
    ctrl = $controller('requestsController', { $scope: scope });
  }));

  afterEach(function() {
    scope.$destroy();
  });

  it('should fill properties from result from xhr requests', function() {
    var unresolvedResponse = [];

    expect(ctrl.usersList).toEqual(unresolvedResponse);
    expect(ctrl.requestsList).toEqual(unresolvedResponse);
    expect(ctrl.projectsList).toEqual(unresolvedResponse);
    expect(ctrl.requestsCommentsList).toEqual(unresolvedResponse);
    expect(ctrl.costEstimationsList).toEqual(unresolvedResponse);
    expect(ctrl.regionsList).toEqual(unresolvedResponse);

    $httpBackend.flush();

    expect(ctrl.usersList).toEqual(testData);
    expect(ctrl.requestsList).toEqual(testData);
    expect(ctrl.projectsList).toEqual(testData);
    expect(ctrl.requestsCommentsList).toEqual(testData);
    expect(ctrl.costEstimationsList).toEqual(testData);
    expect(ctrl.regionsList).toEqual(testData);
  });
});

And this gives me this error :

Expected [ $promise: Promise({ $$state: Object({ status: 0 }) }), $resolved: false ] to equal [ ].

So, I tried to change my unresolvedREsponse variable as follows :

var unresolvedResponse = [ $promise: Promise({ $$state: Object({ status: 0 }) }), $resolved: false ];

But this is an invalid syntax, so I changed it to :

var unresolvedResponse = { $promise: Promise({ $$state: Object({ status: 0 }) }), $resolved: false };

But I'm then getting the following error :

TypeError: undefined is not a promise

Finally, in order to check if the rest was ok, I completly removed the tests that occured before the API response, which give an it(...) like this :

  it('should fill properties from result from xhr requests', function() {
    $httpBackend.flush();

    expect(ctrl.usersList).toEqual(requestData);
    expect(ctrl.requestsList).toEqual(requestData);
    expect(ctrl.projectsList).toEqual(requestData);
    expect(ctrl.requestsCommentsList).toEqual(requestData);
    expect(ctrl.costEstimationsList).toEqual(requestData);
    expect(ctrl.regionsList).toEqual(requestData);
  });

But then, the error becomes :

Error: Unexpected request: GET http://ift.tt/1lwn9sY

Expected GET /users

So, in the end, what is the proper response of an unresolved $resource in order to fix my first error ?

And also, why do I get an unexpected request error with the full url and how to fix it ?

Aucun commentaire:

Enregistrer un commentaire