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

查看:30
本文介绍了使用 $httpBackend 单元测试 AngularJS 控制器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的一生中,我无法让 $httpBackend 在执行 $http get 请求的控制器上工作.我已经尝试了几个小时了 =)

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

  • 注释掉控制器中的 $http.get() 请求
  • 注释掉测试中的httpMock.flush()"
  • 并更改pig"和dog"以匹配

也就是说,它是一个有效的、有效的测试和应用程序.

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");
  });

});

这是我在 shell 中得到的错误:

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. 控制器在之前被创建,httpMock被配置为以pig响应.expectGet 调用应该在实例化控制器之前发生.
  2. httpMock 需要刷新请求
  3. httMock.when 是不必要的,只要你有 expectGet
  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

工作示例: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");
  });
});

这篇关于使用 $httpBackend 单元测试 AngularJS 控制器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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