Единичное тестирование Контроллер AngularJS с $httpBackend
В течение жизни я не могу заставить $httpBackend работать над контроллером, который выполняет запрос $http get. Я пробовал часами сейчас =)
Я уменьшил это до самой простой формы, которую я могу ниже. Тест проходит, если I
- закомментируйте запрос $http.get() в контроллере
- закомментируйте "httpMock.flush()" в тесте
- и измените "свиньи" и "собака" на соответствие
То есть, это действительный рабочий тест и приложение.
Если я верну его обратно, я получу ошибку, показанную внизу.
приложение/JS/app.js
// Declare a module which depends on filters and services.
var myApp = angular
.module('myApp', ['ngRoute', 'myApp.filters', 'myApp.services',
'myApp.directives'])
.config(['$routeProvider' , function($routeProvider) {
$routeProvider
.when("/dashboard", {
templateUrl: "partials/dashboard.html",
controller: cDashboard
})
.otherwise({redirectTo: "/dashboard"});
}]);
// Pre-define our main namespace modules.
angular.module('myApp.directives' , []);
angular.module('myApp.filters' , []);
angular.module('myApp.services' , []);
angular.module('myApp.controllers', []);
приложение/JS/controller.js
function cDashboard ($scope, $http) {
$scope.data = "dog";
// Fetch the actual data.
$http.get("/data")
.success(function (data) { $scope.data = data })
.error(function () {});
}
cDashboard.$inject = [ '$scope', '$http' ];
Тест/блок/controllerSpec.js
describe('cDashboard', function(){
var scope, ctrl, httpMock;
beforeEach(inject(function ($rootScope, $controller, $http, $httpBackend) {
scope = $rootScope.$new();
ctrl = $controller('cDashboard', {$scope: scope});
httpMock = $httpBackend;
httpMock.when("GET", "/data").respond("pig");
}));
it("should get 'pig' from '/data'", function () {
httpMock.expectGET("/data").respond("pig");
expect(scope.data).toBe("pig");
});
});
И это ошибка, которую я получаю в оболочке:
INFO [watcher]: Changed file "/home/myApp/test/unit/controller/cDashboard.js".
Chrome 26.0 (Linux) cDashboard should get 'pig' from '/data' FAILED
Error: No pending request to flush !
at Error (<anonymous>)
at Function.$httpBackend.flush (/home/myApp/test/lib/angular/angular-mocks.js:1171:34)
at null.<anonymous> (/home/myApp/test/unit/controller/cDashboard.js:15:18)
Chrome 26.0 (Linux): Executed 1 of 1 (1 FAILED) (0.326 secs / 0.008 secs)
Ответы
Ответ 1
В тестовом коде есть пара проблем:
- Контроллер создается до того, как
httpMock
настроен на ответ с помощью pig
. Вызов expectGet
должен произойти до создания экземпляра контроллера.
-
httpMock
необходимо очистить запрос
-
httMock.when
не требуется, если у вас есть expectGet
Рабочий пример: http://plnkr.co/edit/lUkDMrsy1KJNai3ndtng?p=preview
describe('cDashboard', function(){
var scope, controllerService, httpMock;
beforeEach(inject(function ($rootScope, $controller, $httpBackend) {
scope = $rootScope.$new();
controllerService = $controller;
httpMock = $httpBackend;
}));
it("should get 'pig' from '/data'", function () {
httpMock.expectGET("/data").respond("pig");
ctrl = controllerService('cDashboard', {$scope: scope});
httpMock.flush();
expect(scope.data).toBe("pig");
});
});