单元测试AngularJS控制器$ httpBackend [英] Unit testing AngularJS controller with $httpBackend
问题描述
有关我的生活,我不能得到$ httpBackend到控制器,做一个$ HTTP GET请求上工作。我试过了好几个小时,现在=)
我已经减少下面这最简单的形式,我可以。测试通过,如果我
- 注释掉控制器$ http.get()请求
- 注释掉httpMock.flush()中的测试
- 而变猪和狗来匹配
这是,这是一个有效的工作试验和应用。
如果我把它放回,我会在底部显示的错误。
的应用程序/ JS / app.js 的
//声明取决于过滤器和服务模块。
VAR对myApp =角
.module('对myApp',['ngRoute','myApp.filters','myApp.services',
'myApp.directives'])
的.config(['$ routeProvider',函数($ routeProvider){ $ routeProvider
。当(/仪表板,{
templateUrl:谐音/ dashboard.html
控制器:cDashboard
}) 不然的话({redirectTo:/仪表板});
}]);// pre-定义我们的主命名空间的模块。
angular.module('myApp.directives',[]);
angular.module('myApp.filters',[]);
angular.module('myApp.services',[]);
angular.module('myApp.controllers',[]);
的应用程序/ JS / controller.js 的
函数cDashboard($范围,$ HTTP){
$ scope.data =狗; //获取的实际数据。
$ http.get(/数据)
.success(功能(数据){$ scope.data =数据})
.error(函数(){});
}。cDashboard $注射='$范围,$ HTTP'];
的测试/单位/ controllerSpec.js 的
描述('cDashboard',函数(){
VAR范围,CTRL httpMock; beforeEach(注(函数($ rootScope,$控制器,$ HTTP,$ httpBackend){
范围= $ rootScope $新的()。
CTRL = $控制器('cDashboard',{$范围:适用范围}); httpMock = $ httpBackend;
httpMock.when(GET,/data\").respond(\"pig);
})); 它(,功能应当从'/数据'得到'猪'(){
。httpMock.expectGET(/数据)响应(猪);
期待(scope.data).toBe(猪);
});});
这是我在shell得到错误:
INFO [观察家]:改变文件/home/myApp/test/unit/controller/cDashboard.js。
Chrome的26.0(Linux)的cDashboard应该从'/数据失败得到'猪'
错误:没有挂起请求刷新!
在错误(小于匿名>)
在功能。$ httpBackend.flush(/home/myApp/test/lib/angular/angular-mocks.js:1171:34)
在空<&匿名GT; (/home/myApp/test/unit/controller/cDashboard.js:15:18)
Chrome的26.0(Linux)的:执行1 1(1失败)(0.326秒/ 0.008秒)
有在测试code一对夫妇的问题:
- 控制器创建的前的的
httpMock
配置与猪回应
。在expectGet
调用应该实例化控制器之前发生的。 - 的
httpMock
需要冲洗的要求 - 的
httMock.when
是不必要的,只要你有expectGet
的例子:<一href=\"http://plnkr.co/edit/lUkDMrsy1KJNai3ndtng?p=$p$pview\">http://plnkr.co/edit/lUkDMrsy1KJNai3ndtng?p=$p$pview
描述('cDashboard',函数(){
VAR范围,controllerService,httpMock; beforeEach(注(函数($ rootScope,$控制器,$ httpBackend){
范围= $ rootScope $新的()。
controllerService = $控制器;
httpMock = $ httpBackend;
})); 它(,功能应当从'/数据'得到'猪'(){
。httpMock.expectGET(/数据)响应(猪);
CTRL = controllerService('cDashboard',{$范围:适用范围});
httpMock.flush();
期待(scope.data).toBe(猪);
});
});
For the life of me I can't get $httpBackend to work on a controller that does an $http get request. I've tried for hours now =)
I've reduced this to the simplest form I can below. The test passes if I
- comment out the $http.get() request in the controller
- comment out the "httpMock.flush()" in the test
- and change "pig" and "dog" to match
That is, it's a valid, working test and app.
If I put it back in, I get the error shown at the bottom.
app/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', []);
app/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' ];
test/unit/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");
});
});
And this is the error I get in the shell:
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)
There are a couple problems in your test code:
- The controller is created before the
httpMock
is configured to respond withpig
. TheexpectGet
call should happen before instantiating the controller. - The
httpMock
needs to flush the request - The
httMock.when
is unnecessary so long as you have theexpectGet
Working example: 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");
});
});
这篇关于单元测试AngularJS控制器$ httpBackend的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!