单元测试AngularJS控制器$ httpBackend [英] Unit testing AngularJS controller with $httpBackend

查看:149
本文介绍了单元测试AngularJS控制器$ 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一对夫妇的问题:


  1. 控制器创建的的的 httpMock 配置与猪回应。在 expectGet 调用应该实例化控制器之前发生的。

  2. httpMock 需要冲洗的要求

  3. 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:

  1. The controller is created before the httpMock is configured to respond with pig. The expectGet call should happen before instantiating the controller.
  2. The httpMock needs to flush the request
  3. The httMock.when is unnecessary so long as you have the expectGet

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆