2017-03-06 69 views
1

我正在嘗試爲使用Keycloak進行身份驗證的Angular應用程序編寫測試套件。單元測試啓用Keycloak的Angular應用程序

然而,隨着Keycloak需要你手動引導角,併成立了幾個攔截器,我不能解僱任何測試由於以下錯誤:

Error: $injector:unpr 
Unknown Provider: AuthProvider <- Auth <- authInterceptor <- $http <- $templateRequest <- $route 

這是攔截器的代碼,引發錯誤:

angular.module('MPMReportGenerator') 
    .factory('authInterceptor', function authInterceptor ($q, Auth, $log) { 
    return { 
     request: function (config) { 
     var deferred = $q.defer() 
     Auth.updateToken(5).success(function() { 
      config.headers = config.headers || {} 
      config.headers.Authorization = 'Bearer ' + Auth.token 
      deferred.resolve(config) 
     }).error(function() { 
      deferred.reject('Failed to refresh token') 
     }) 
     $log.info(deferred.promise) 
     return deferred.promise 
     } 
    } 
    }) 

我的想法是,我應該嘲笑攔截,只是有它返回請求。然而,我沒有看到我怎麼做到這一點,因爲這個攔截器從來沒有作爲依賴注入到任何地方,它只是用上面的塊聲明,就是這樣。我對嘲笑服務的理解是,他們需要注入某個地方進行嘲弄。

我的keycloak into Angular的實現直接來自他們的例子,如果有幫助的話。

編輯

我一直在試圖注入嘲笑驗證模塊爲我寫了一個測試服務,但仍然沒有改變。
我對單元測試一般都很陌生,所以我有點失落,試圖追蹤這種情況。我覺得我知道問題出在哪裏,但不知道如何解決它(Auth服務在應用程序引導過程中添加,我需要嘲笑它的工作,但似乎我不知道如何/在哪裏正確地嘲笑吧)

這裏是整個測試代碼:

describe('Services', function() { 
    'use strict' 

    beforeEach(module('MPMReportGenerator')) 

    module(function ($provide) { 
    $provide.factory('Auth', function() { 
     return null 
    }) 
    }) 

    var sectionService, $httpBackend, mockAuth 
    beforeEach(inject(function (_sectionService_, _$httpBackend_, Auth) { 
    sectionService = _sectionService_ 
    $httpBackend = _$httpBackend_ 
    mockAuth = Auth 
    })) 

    it('should get sections', function() { 
    $httpBackend.expect('GET', '/MPMReportGenerator/api/categories/all').respond(200) 

    sectionService.getSections() 

    expect($httpBackend.flush).not.toThrow() 
    }) 
}) 

編輯2

我已經設法通過使身份驗證的模擬版本,以獲得過去我最初的錯誤。
我現在面臨的問題是實現Keycloak的Javascript庫的模擬版本。

我目前的模擬代碼如下:

beforeEach(module(function ($provide) { 
    $provide.factory('Auth', function ($q) { 
     return { 
     updateToken: function (minValidity) { 
      return { 
      success: function (fn) { 
       var deferred = $q.defer() 
       deferred.resolve('') 
       fn(deferred.promise) 
      }, 
      error: function (fn) { 
       var deferred = $q.defer() 
       deferred.resolve('Error') 
       fn(deferred.promise) 
      } 
      } 
     }, 
     token: 'thisisafaketokenfortesting' 
     } 
    }) 
    })) 

,並拋出這個錯誤:

Expected function not to throw, but it threw TypeError: undefined is not an object (near '...}).error(function() {...'). 
    target/MPMReportGenerator-1.0.0/js/app.service.spec.js:42:43 
    [email protected]://localhost:9876/context.js:151:17 

我的實際測試是這樣的:

it('should get sections', function() { 
    $httpBackend.expect('GET', '/MPMReportGenerator/api/categories/all').respond(200) 
    sectionService.getSections() 
    expect($httpBackend.flush).not.toThrow() 
    }) 
+0

也許你應該注入「驗證」你的模塊 – papakias

+0

是啊,這就是我認爲是問題。在Keycloak初始化後引導應用程序時會創建「Auth」服務,所以我需要對所有工作進行模擬。 我用當前(仍然不工作)的代碼添加了一個編輯,我嘗試注入一個模擬的Auth服務。 –

+0

嘗試用angular.module('MPMReportGenerator','Auth')替換舊代碼的第一行。還可以通過這種方式將Auth添加到您的應用程序模塊中。這能解決什麼問題嗎? – papakias

回答

1

我終於想通了。

這裏是必要的代碼,如果有人想測試與keycloak的角度應用:如果你打算測試中提供的攔截

beforeEach(
    module(function ($provide) { 
    $provide.factory('Auth', function ($q) { 
     return { 
     updateToken: function (minValidity) { 
      return { 
      success: function() { 
       return { 
       error: function() { 
        var deferred = $q.defer() 
        return deferred.promise 
       } 
       } 
      } 
      } 
     }, 
     token: 'thisisafaketokenfortesting' 
    } 
    }) 
})) 

請注意,你可能會需要模擬keycloak庫的其它部分官方的例子。

編輯

不要使用上面的代碼,下面的效果要好得多:

$provide.factory('Auth', function() { 
    return { 
    updateToken: function (minValidity) { 
     return { 
     success: function() { 
      return this 
     }, 
     error: function() { 
      return this 
     } 
     } 
    }, 
    token: 'thisisafaketokenfortesting' 
    } 
})