测试控制器与茉莉花的承诺

时间:2014-07-12 21:26:35

标签: angularjs unit-testing controller jasmine

我正在为使用服务的控制器编写测试。 这是控制器:

  $scope.loadData = function(){
UserDataService.query({
        user_id: $routeParams.user_id }
).$promise.then (function (data) {
    $scope.labels = data.label;
    $scope.data = data.data;
    $.each($scope.data, function (key, value) {
        $scope.original_keys.push(key);
        $scope.original_data.push(value);
    });
},
function (error) {
    $location.path("/404");

});
};
$scope.loadData();

这就是服务:

  angular.module('services')
.factory('UserDataService', ['$resource', function ($resource) {
var hostURL = 'http://localhost:9000';

    return $resource( hostURL + '/api/users/:user_id',
        {user_id: '@user_id'}, {
            'query': {method: 'GET'}

        });

}]);

这是我写过的测试:

ddescribe('UsersCtrl - Mattia Version', function () {

var scope, location, fakeDataService, fakeEditService, routeParams, UsersCtrl;
var getDeferred;
var data={label:["a","b"]};
beforeEach(function() {
    module('maaperture');
});

beforeEach(angular.mock.inject(function( $rootScope, $location, $routeParams, $controller, $q) {
    scope = $rootScope.$new();
    location = $location;
    routeParams = $routeParams;
    fakeDataService = {
        query: function() {return $http().then();}
    };

    getDeferred = $q.defer();
    getDeferred.resolve(data);

    spyOn(fakeDataService, 'query').andReturn(getDeferred);


    UsersCtrl = $controller('UsersCtrl', {
        '$scope': scope,
        '$location': location,
        'UserDataService': fakeDataService,
        'UserEditService': fakeEditService,
        '$routeParams': routeParams
    });
}));

it('should call stuff', function () {
    expect(fakeDataService.query).toHaveBeenCalled();
});

it('should set some data on the scope when successful', function () {
    scope.loadData();
    scope.$apply();
    scope.$digest();
    expect(fakeDataService.get).toHaveBeenCalled();
    expect(scope.data).toEqual(getResponse.data);
});

它应该是正确的,因为我已经遵循了很多指南,但我一直在

 TypeError: Cannot read property 'then' of undefined

每次我运行它。 我用业力和茉莉花进行测试。无法弄清楚我为什么会收到这个错误。

1 个答案:

答案 0 :(得分:1)

因为延迟对象没有$ promise属性。使用$ httpBackend是更好的方法。

试试这个:

describe('UsersCtrl - Mattia Version', function () {

  var scope, routeParams, UsersCtrl;
  var $httpBackend;

  var data = {label: ["a", "b"]};

  beforeEach(module('maaperture', 'services', 'ngResource', 'ngRoute'));

  beforeEach(angular.mock.inject(function ($rootScope, $routeParams, $controller, _$httpBackend_) {
    scope = $rootScope.$new();
    routeParams = $routeParams;
    $httpBackend = _$httpBackend_;

    routeParams.user_id = 1;

    UsersCtrl = $controller('UsersCtrl', {
      '$scope': scope,
      '$routeParams': routeParams
    });
  }));

  it('should set some data on the scope when successful', function () {
    // Given
    $httpBackend.whenGET('http://localhost:9000/api/users/' + routeParams.user_id).respond(200, data);

    // When
    scope.loadData();
    $httpBackend.flush();

    // Then
    expect(scope.data).toEqual(data.data);
  });
});

服务:

angular.module('services', [])
  .factory('UserDataService', ['$resource', function ($resource) {
    var hostURL = 'http://localhost:9000';

    return $resource(hostURL + '/api/users/:user_id',
      {user_id: '@user_id'}, {
        'query': {method: 'GET'}
      });
  }]);

希望这有帮助。