2015-01-20 4 views
0

Я пытаюсь протестировать контроллер, а не требовать, чтобы я издевался над сервисом, который я использую для получения данных. В настоящее время я получаю сообщение об ошибке сказав функции не определено на этой линии:Единичное тестирование углового кода с помощью сервиса с использованием Jasmine

dataServiceMock = jasmine.createSpyObj('dataService', ['getFunctionStuff']); 

Согласно другим примерам и руководств это должно работать нормально.

Вот мой код, включая тестовый файл, сервис и контроллер.

Контроллер:

var app = angular.module('myApp', []); 

app.controller('MainCtrl', function($scope, dataService) { 

    dataService.getFunctionStuff($scope.foo) 
     .then(function(data) { 
     $scope.test = data; 
     }); 

}); 

Услуги:

app.factory('dataService', function ($timeout, $q){ 

    function getFunctionStuff(formData) { 
      return $http.post('../randomAPICall', formData).then(function(data) { 
       return data; 
      }); 
     }; 

}); 

Тесты:

describe('Testing a controller', function() { 
    var $scope, ctrl, $timeout; 

    var dataServiceMock; 

    beforeEach(function(){ 

    dataServiceMock = jasmine.createSpyObj('dataService', ['getFunctionStuff']); 

    module('myApp'); 

    inject(function($rootScope, $controller, $q, _$timeout_) { 

     $scope = $rootScope.$new(); 

     dataServiceMock.getFunctionStuff.and.ReturnValue($q.when('test')); 

     $timeout = _$timeout_; 

     ctrl = $controller('MainCtrl', { 
     $scope: $scope, 
     dataService: dataServiceMock 
     }); 
    }); 
    }); 

    it('should update test', function(){ 
    expect($scope.test).toEqual('test');  
    }); 
}); 

Вот plunker его: http://plnkr.co/edit/tBSl88RRhj56h3Oiny6S?p=preview

+0

Я опубликовал 2 способа выполнить единичный тест. Один из них - ваш способ создать шпиона, другой - использовать '$ httpBackend', который является обычным способом. – elaijuh

ответ

1

Как вы используете жасмин 2.1,API - .and.returnValue. И в тестовой спецификации, сделать $scope.$apply() до того then

describe('Testing a controller', function() { 
    var $scope, ctrl, $timeout; 

    var dataServiceMock; 

    beforeEach(function() { 

     dataServiceMock = jasmine.createSpyObj('dataService', ['getFunctionStuff']); 

     module('myApp'); 

     inject(function ($rootScope, $controller, $q, _$timeout_) { 

      $scope = $rootScope.$new(); 

      dataServiceMock.getFunctionStuff.and.returnValue($q.when('test')); 

      $timeout = _$timeout_; 

      ctrl = $controller('MainCtrl', { 
       $scope: $scope, 
       dataService: dataServiceMock 
      }); 
     }); 
    }); 

    it('should update test', function() { 
     $scope.$apply(); 
     expect($scope.test).toEqual('test'); 
    }); 
}); 
+0

Можете ли вы объяснить, почему мне нужно использовать $ scope. $ Apply()? Я пробовал это и отлично работал, я просто хотел бы понять. – Blake

+0

@Blake - вам нужно разложить разрешение обещания на функции «then», используя $ apply(). обратитесь к [угловому документу $ q] (https://docs.angularjs.org/api/ng/service/$q) – elaijuh

0

Вот еще один распространенный способ проверить $http на $httpBackend:

app.js

var app = angular.module('myApp', []); 

app.controller('MainCtrl', function($scope, dataService) { 

    dataService.getFunctionStuff($scope.foo) 
     .then(function(data) { 
     $scope.test = data.data; 
     }); 

}); 

dataService.js

app.factory('dataService', function($http) { 

    function getFunctionStuff(formData) { 
    return $http.post('../randomAPICall', formData).then(function(data) { 
     return data; 
    }); 
    } 

    return { 
    getFunctionStuff: getFunctionStuff 
    }; 

}); 

specs.js

describe('Testing a controller', function() { 
    var $scope, ctrl, $controller, $httpBackend; 

    beforeEach(function(){ 

    module('myApp'); 

    inject(function($injector) { 

     $httpBackend = $injector.get('$httpBackend'); 
     $scope = $injector.get('$rootScope').$new(); 
     $controller = $injector.get('$controller'); 

     $scope.foo = 'foo'; 
     $httpBackend.expectPOST('../randomAPICall', 'foo').respond(201, 'test'); 
     ctrl = $controller('MainCtrl', {$scope: $scope}); 
    }); 

    }); 

    it('should update test', function(){ 
    expect($scope.test).not.toBeDefined(); 
    $httpBackend.flush(); 
    expect($scope.test).toEqual('test');  
    }); 
}); 
Смежные вопросы