2013-06-27 52 views
6

我有一個使用角度翻譯(https://github.com/PascalPrecht/angular-translate)的應用程序。翻譯在應用程序中通過瀏覽器效果很好,但當我嘗試測試任何控制器時,我得到錯誤:意外的請求:GET語言環境/語言環境en.json。由於translate在啓動時對語言文件執行GET請求,因此如何對我的控制器進行單元測試?如何測試在App Config中初始化的角度翻譯控制器?

我使用與Karma一樣的yeoman角發生器。


App.js:

angular.module('myApp', ['ngCookies', 'ui.bootstrap', 'pascalprecht.translate']) 
    .config(function ($routeProvider, $locationProvider, $translateProvider) { 

    $routeProvider 
     .when('/', { 
     templateUrl: 'views/main.html', 
     controller: 'MainCtrl' 
     }) 
     .otherwise({ 
     redirectTo: '/' 
     }); 

     $translateProvider.useStaticFilesLoader({ 
     prefix: 'locale/locale-', 
     suffix: '.json' 
     }); 
     $translateProvider.uses('en'); 
     $translateProvider.useLocalStorage(); 
    }); 

控制器測試:

describe('Controller: DocumentationCtrl', function() { 

    // load the controller's module 
    beforeEach(module('myApp')); 

    var DocumentationCtrl, 
    scope, 
    $httpBackend; 

    // Initialize the controller and a mock scope 
    beforeEach(inject(function ($controller, $rootScope, $injector) { 
    $httpBackend = $injector.get('$httpBackend'); 
    scope = $rootScope.$new(); 
    DocumentationCtrl = $controller('DocumentationCtrl', { 
     $scope: scope 
    }); 
    })); 

    it('should attach a list of awesomeThings to the scope', function() { 
    $httpBackend.whenGET('locale/locale-en.json').respond(200, { 
     "TITLE": 'My App' 
    }); 
    expect(scope.awesomeThings.length).toBe(3); 
    }); 

}); 

文檔控制器僅僅是一個標準產生控制器。

回答

5

您必須在配置階段指定首選語言,而不是運行階段。所以$translate.uses('us')變成$translateProvider.preferredLanguage('us')。 同樣適用於useLocalStorage()。這些都是配置$translate服務的方法。

您還應該嘗試避免uses()設置默認語言。改爲使用preferredLanguage()。原因是,$translate.uses()試圖儘快加載i18n文件, 如果有一個cookie或類似的使用另一種語言的鍵,uses()將加載兩個文件,那爲什麼我們介紹preferredLanguage()而且,這應該解決問題。

+0

非常感謝你的回答。我仍然不知道如何測試這個,雖然我切換到preferredLanguage(),所以我的app.config看起來像這樣:$ translateProvider.useStaticFilesLoader({locale/locale-', 後綴:'。json' }); $ translateProvider.preferredLanguage('us'); $ translateProvider.useLocalStorage(); – Zacho

+0

哦,並且出現錯誤是因爲您不希望顯式獲取http獲取請求。所以在你的it()規範中,你應該做如下的事情:$ http.expectGET('locale/locale-us.json');並且不要忘記通過$ http.flush()刷新掛起的響應。 – PascalPrecht

+0

我知道它的工作。解決的辦法是在我的單元測試中初始化應用程序之前使用preferredLanguage()並覆蓋函數。這是一個很大的應用程序,我不希望在每個單元測試中都使用locale expectGET。謝謝! – Zacho

1

避免初始化應用程序級模塊,將您的控制器放在myApp.controllers中並改爲測試此模塊。

「我們建議您將您的應用程序分解爲多個模塊(...)造成這種分離的原因是,在您的測試中,通常需要忽略初始化代碼,這往往很難測試。 「

http://docs.angularjs.org/guide/module

+1

我確實嘗試過,但它似乎仍然走的路,但問題仍然與意想不到的GET /locale/en-us.json相同。 – Zacho

0

我認爲你有一個錯誤的順序:設置爲角轉換試圖調用uses(lang)後加載的語言權(塊,確實後)。

在anguluar-translate中開發適配器時,我們遇到了類似的問題。嘗試查看https://github.com/PascalPrecht/angular-translate-loader-url/blob/16e559030bce819e8ca1b82fed7163286b57bafe/test/unit/translateUrlLoaderSpec.js哪些是url loader插件的測試。

控制器是否應該在稍後注入?

+0

我也在想,但是我已經嘗試過在幾個不同的位置放置expectGET/whenGET。我認爲這個問題是你可能會遇到的一個問題,那就是雞和雞蛋問題。基本上我需要在應用程序運行之前定義whenGET,但應用程序需要首先實例化。任何如何實現這個目標的例子?我是否需要首先在我的測試中加載翻譯,然後是我的應用程序? – Zacho