2014-01-16 31 views
4

所以我對JavaScript和AngularJS的世界很陌生,因此我的代碼還不如它應該的那麼好,但它正在改進。不過,我開始學習並實現一個帶有REST後端的簡單登錄頁面。登錄表格提交後,一個認證令牌返回並設置爲這樣

$http.defaults.headers.common['X-AUTH-TOKEN'] = data.authToken; 

這工作得很好,只要我手動測試它默認的HTTP標頭屬性,但是這不是去讓我的方式想要實現一個單元測試,檢查是否設置了X-AUTH-TOKEN標頭。

有沒有辦法用$ httpBackend來檢查?例如,我有以下測試:

describe('LoginController', function() { 
    var scope, ctrl, $httpBackend; 

    // Load our app module definition before each test. 
    beforeEach(module('myApp')); 

    // The injector ignores leading and trailing underscores here (i.e. _$httpBackend_). 
    // This allows us to inject a service but then attach it to a variable 
    // with the same name as the service. 
    beforeEach(inject(function (_$httpBackend_, $rootScope, $controller) { 
     $httpBackend = _$httpBackend_; 
     scope = $rootScope.$new(); 
     ctrl = $controller('LoginController', {$scope: scope}, {$http: $httpBackend}, {$location: null}); 
    })); 

    it('should create an authToken and set it', function() { 
     $httpBackend.expectPOST('http://localhost:9000/login', '200').respond(200, '{"authToken":"52d29fd63004c92b972f6b99;65e922bc-5e33-4bdb-9d52-46fc352189fe"}'); 
     scope.login('200'); 
     $httpBackend.flush(); 

     expect(scope.data.authToken).toBe('52d29fd63004c92b972f6b99;65e922bc-5e33-4bdb-9d52-46fc352189fe'); 
     expect(scope.loginValidationOverallError).toBe(false); 
     expect(scope.status).toBe(200); 
    }); 

我的控制器看起來是這樣的:

.controller('LoginController', ['$scope', '$http', '$location', 
    function ($scope, $http, $location) { 

     // Login Stuff 
     $scope.data = {}; 
     $scope.status = {}; 
     $scope.loginValidationOverallError = false; 
     $scope.login = function (user) { 
      $http.post('http://localhost:9000/login', user).success(function (data, status) { 

       $scope.data = data; 
       $scope.status = status; 
       $scope.loginValidationOverallError = false; 


       console.log($scope.status, $scope.data); 
       $http.defaults.headers.common['X-AUTH-TOKEN'] = data.authToken; 
       $location.path('/user'); 

      }).error(function (data, status) { 
        console.log(status + ' error'); 
        $scope.loginValidationOverallError = true; 
       }); 

     }; 
     ... 

我查了一下資料,在http://docs.angularjs.org/api/ngMock.$httpBackend但我不知道,如果最後的測試實際上是適用於我的代碼(以及如何該代碼實際上測試的東西)

it('should send auth header', function() { 
    var controller = createController(); 
    $httpBackend.flush(); 

    $httpBackend.expectPOST('/add-msg.py', undefined, function(headers) { 
     // check if the header was send, if it wasn't the expectation won't 
     // match the request and the test will fail 
     return headers['Authorization'] == 'xxx'; 
    }).respond(201, ''); 

    $rootScope.saveMessage('whatever'); 
    $httpBackend.flush(); 
}); 

回答

7

我面臨着同樣的問題,我終於解決了它。這是非常棘手的

周守軍代碼AuthenticationService.login()函數

$http.post(...) 
    .success(function(data) { 
    ... 
    $http.defaults.headers.common['Authorization'] = data.oauth_token; 
    }); 

測試代碼

beforeEach(inject(function(_$httpBackend_,AuthenticationService) { 
    $httpBackend = _$httpBackend_; 
    $authenticationService = AuthenticationService; 
})); 

it('should login successfully with correct parameter', inject(function($http) { 
// Given 
... 
... 
var fakeResponse = { 
    access_token: 'myToken' 
} 

$httpBackend.expectPOST('oauth/token',urlEncodedParams, function(headers) { 
     return headers['Content-Type'] === 'application/x-www-form-urlencoded'; 
}).respond(200, fakeResponse); 

// When 
$authenticationService.login(username,password); 


// Then 
$httpBackend.flush(); 
expect($http.defaults.headers.common['Authorization']).toBe('myToken'); 

這裏是默認的頭被設置在真正的$ http服務,而不是模擬$ httpBackend。這就是爲什麼你應該注入真正的$ http服務

我試圖測試$ httpBackend卻得到了一個「未定義」錯誤,因爲$ httpBackend沒有「默認值」屬性

+0

感謝,我看到,注入(功能($ http)是訣竅 – Luk

相關問題