2013-03-20 59 views
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(); 
    }); 
}); 

我ge t出現以下錯誤:

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

有人知道我在做什麼錯嗎?提前致謝。

回答

8

$ http使用$httpBackend與外部資源交談。你還嘲笑$httpBackend,但控制器仍需要對它說話槽$http s接口。

這應做到:

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

謝謝這真的有幫助,傻了我。 – 2013-04-25 15:36:38

+0

但是你沒有修改$ httpBackend的實際實現。那麼Angular知道如何在真正的$ httpBackend對象上調用(不管)方法,而是在調用$ http.get()時調用httpMock? (這是Angular的新手) – Nikhil 2013-09-26 22:39:52

+1

Nikhil,當$ http初始化時,$ http會要求$ httpBackend。 $ httpBackend是一個單例(只存在一個實例),httpMock是對它的引用。註冊回調函數,並在測試和$ http之間共享的$ httpBackend實例上執行這些工作。 – 2013-11-28 08:44:00

0

您需要的預期()調用httpMock.flush()。 flush調用模擬從「後端」返回的響應,調用綁定到http請求的成功函數。

+0

我不知道,()有沖洗先走的原因,所以我已經學到了一些東西,累了左右逢源,我仍然得到同樣的錯誤。 – 2013-03-21 09:30:31

3

您無法手動將$ http服務替換爲您的控制器的$ httpBackend服務。

變化

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

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

它應該工作。