7

我有一个简单的控制器,我需要它做的第一件事就是为范围分配一个值。

function TestCtrl($scope, $http) {
    $scope.listForms = 'some list';
}

控制器的以下测试按预期工作:

describe('Testing a controller', function() {

    var ctrl, scope, httpMock;

    beforeEach(inject(function($injector) {
        scope = $injector.get('$rootScope').$new();
        ctrl = $injector.get('$controller');
        ctrl(TestCtrl, { $scope: scope });
    }));

    it("assigns to scope", function() {
      expect(scope.listForms).toMatch("some list");
    });
});

但是当我更改函数以从我的 API 获取列表时

function TestCtrl($scope, $http) {
  $http.get('/api/listForms').success(function(list) {
    $scope.aListOfForms = 'some list';
  });
}

并且测试更改为

describe('Testing a controller', function() {

    var ctrl, scope, httpMock;

    beforeEach(inject(function($injector) {
        httpMock = $injector.get('$httpBackend');

        scope = $injector.get('$rootScope').$new();
        httpMock.when('GET', '/tactical/api/listOrderForms').respond("an order form");

        ctrl = $injector.get('$controller');
        ctrl(TestCtrl, {
            $scope: scope,
            $http: httpMock
        });
    }));

    it("gets the list from the api and assigns it to scope", function() {
      httpMock.expectGET('tactical/api/listOrderForms');
      expect(scope.orderFormList).toMatch("an order form");
      httpMock.flush();
    });
});

我收到以下错误:

TypeError: 'undefined' is not a function
Expected undefined to match 'an order form'.
Error: No pending request to flush !

有谁知道我做错了什么?提前致谢。

4

3 回答 3

8

$http 用于$httpBackend与外部资源对话。你已经 mocked$httpBackend了,但是控制器仍然需要通过$https 接口与它对话。

这应该这样做:

describe('Testing a controller', function() {

    var ctrl, scope, httpMock;

    beforeEach(inject(function($controller, $rootScope, $httpBackend) {
        httpMock = $httpBackend;

        scope = $rootScope.$new();
        httpMock.when('GET', '/tactical/api/listOrderForms').respond("an order form");

        ctrl = $controller;
        ctrl(TestCtrl, {
            $scope: scope
        });
    }));

    it("gets the list from the api and assigns it to scope", function() {
      httpMock.expectGET('tactical/api/listOrderForms');
      httpMock.flush();
      expect(scope.orderFormList).toMatch("an order form");
    });
});
于 2013-04-20T12:47:53.637 回答
3

您不能手动将 $http 服务替换为控制器的 $httpBackend 服务。

改变

    ctrl(TestCtrl, {
        $scope: scope,
        $http: httpMock
    });

    ctrl(TestCtrl, {
        $scope: scope
    });

它应该工作。

于 2013-04-02T00:13:56.320 回答
0

You need to call httpMock.flush() before the expect(). The flush call simulates the response returning from the "back end," calling the success function that was bound to the http request.

于 2013-03-20T20:36:10.323 回答