How do I test controllers with Angular Translate i

2019-01-22 23:58发布

问题:

I have an app that uses Angular Translate (https://github.com/PascalPrecht/angular-translate). Translate works great in the application via browser but when I try to test any controller I get Error: Unexpected request: GET locale/locale-en.json. How do I unit test my controllers since translate does a GET request for the language file on startup?

I am using the yeoman angular generator with Karma.


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();
  });

Controller Test:

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);
  });

});

The Documentation Controller is just a standard generated controller.

回答1:

You have to specify the preferred language within config phase rather then run phase. So $translate.uses('us') becomes $translateProvider.preferredLanguage('us'). Same goes for useLocalStorage(). These are all methods to configure $translate service.

You should also try to avoid uses() to set a default language. Use preferredLanguage() instead. The reason for this is, that $translate.uses() tries to load a i18n file as soon as possible, if there's a cookie or similar which uses another language key, uses() will load two files, that why we introduced preferredLanguage() And yea, this should solve the problem.



回答2:

Avoid initialize application level module, put your controllers in myApp.controllers and test this module instead.

"We recommend that you break your application to multiple modules. (...) The reason for this breakup is that in your tests, it is often necessary to ignore the initialization code, which tends to be difficult to test."

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



回答3:

I think you have a wrong order: The setup for angular-translate tries to loading the language right after calling uses(lang) (after the block, indeed).

We had similar problems when developing the adapters in anguluar-translate. Try to look into https://github.com/PascalPrecht/angular-translate-loader-url/blob/16e559030bce819e8ca1b82fed7163286b57bafe/test/unit/translateUrlLoaderSpec.js which are the tests for the url loader plugin.

Should the controller not be injected a step later?