首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用angular-translate进行单元测试

如何使用angular-translate进行单元测试
EN

Stack Overflow用户
提问于 2013-09-18 23:23:41
回答 11查看 29K关注 0票数 40

我使用angular translate from here (http://pascalprecht.github.io/angular-translate/),它工作得很好,但它错误地破坏了我控制器单元测试:

代码语言:javascript
复制
Unexpected request: GET scripts/i18n/locale-en.json

我不明白为什么?

我使用yeoman并使用karma进行测试。

app.js:

代码语言:javascript
复制
'use strict';

(function() {

  angular.module('wbApp', ['authService', 'authUserService', 'checkUserDirective', 'ui.bootstrap', 'pascalprecht.translate'])
    .config(function($routeProvider) {
      $routeProvider
        .when('/', {
          templateUrl: 'views/login.html',
          controller: 'LoginCtrl',
          access: {
            isFree: true
          }
        })
        .when('/main', {
          templateUrl: 'views/main.html',
          controller: 'MainCtrl',
          access: {
            isFree: false
          }
        })
        .otherwise({
          redirectTo: '/'
        });
    });

})();

configTranslate.js:

代码语言:javascript
复制
'use strict';

(function() {

  angular.module('wbApp')
    .config(['$translateProvider',
      function($translateProvider) {

        $translateProvider.useStaticFilesLoader({
            prefix: 'scripts/i18n/locale-',
            suffix: '.json'
        });

        $translateProvider.preferredLanguage('en');

      }]);

})();

karma.conf.js:

代码语言:javascript
复制
files = [

  ...

  'app/bower_components/angular-translate/angular-translate.js',
  'app/bower_components/angular-translate-loader-static-files/angular-translate-loader-static-files.js',

  ...

];

控制器测试:

代码语言:javascript
复制
'use strict';

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

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

  var LoginCtrl, scope, location, httpMock, authUser;

  // Initialize the controller and a mock scope
  beforeEach(inject(function($controller, $rootScope, $location, $httpBackend, AuthUser) {
    authUser = AuthUser;
    location = $location;
    httpMock = $httpBackend;
    scope = $rootScope.$new();

    LoginCtrl = $controller('LoginCtrl', {
      $scope: scope
    });


    httpMock.when('GET', 'scripts/i18n/locale-en.json').passThrough();

  }));

  it(...);

  ...

});

如果我将此代码添加到测试控制器中,则会产生相同的错误:

代码语言:javascript
复制
httpMock.when('GET', 'scripts/i18n/locale-en.json').respond(200);
httpMock.flush();

代码语言:javascript
复制
httpMock.when('GET', 'scripts/i18n/locale-en.json').passThrough();
httpMock.flush();

我发现这个帖子How do I test controllers with Angular Translate initialized in App Config?,但对我没有帮助:/

我在测试中广泛使用了$httpBackend,它工作得很好,但在这种情况下,它是无效的。如果我注释这行:

代码语言:javascript
复制
$translateProvider.preferredLanguage('en');

显然是一个错误,如果我添加了运行时(在我的控制器中)

代码语言:javascript
复制
$translate.uses(local);

我最终会出现同样的错误吗?

因此,我转向转换配置(configTranslate.js)或在运行时是相同的结果:

代码语言:javascript
复制
Unexpected request: GET scripts/i18n/locale-en.json

下面是我测试的语法,或者在"beforeEach(inject(function(...});“

或者在测试中"it('...',function() {...});“

代码语言:javascript
复制
httpMock.expectGET('scripts/i18n/locale-en.json');
httpMock.when('GET', 'scripts/i18n/locale-en.json').passThrough();
httpMock.when('GET', 'scripts/i18n/locale-en.json').respond(data);

在结尾处

代码语言:javascript
复制
httpMock.flush();

我还尝试了$ apply

代码语言:javascript
复制
httpMock.expectGET('scripts/i18n/locale-fr.json');
scope.$apply(function(){
  $translate.uses('fr');
});
httpMock.flush();

什么都没发生,但这个错误还是让我抓狂。

如果你有任何建议

EN

回答 11

Stack Overflow用户

发布于 2014-11-29 01:39:12

这是一个已知问题,请遵循此处的文档:unit testing angular

The solution

不幸的是,这个问题是由角度平移的设计引起的。为了避免这些错误,我们所能做的就是在我们的测试套件中重写我们的模块配置,它根本不使用异步加载器。如果没有异步加载器,就没有XHR,因此不会出现错误。

那么我们如何在运行时为我们的测试套件覆盖我们的模块配置呢?在实例化一个angular模块时,我们总是可以应用一个内联函数,该函数作为配置函数来执行。此配置函数可用于覆盖模块配置,因为我们可以访问所有提供程序。

使用$provide提供程序,我们可以构建一个自定义加载器工厂,然后应该使用它来代替静态文件加载器。

代码语言:javascript
复制
beforeEach(module('myApp', function ($provide, $translateProvider) {

  $provide.factory('customLoader', function () {
    // loader logic goes here
  });

  $translateProvider.useLoader('customLoader');

}));

请在上面提供的链接中阅读更多。

票数 28
EN

Stack Overflow用户

发布于 2015-04-06 23:19:20

我们采取了在单元测试中忽略转换加载器的方法,而不是被迫修改每个规范文件。

一种方法是将加载器配置分离到一个单独的文件中,然后在karma中排除它。

因此,例如,您可以创建文件app-i18n-loader.js (所有其他模块配置都在不同的文件中进行):

代码语言:javascript
复制
    angular
    .module('myApp')
    .config(loaderConfig);

loaderConfig.$inject = ['$translateProvider', '$translatePartialLoaderProvider'];

function loaderConfig($translateProvider, $translatePartialLoaderProvider) {

    $translateProvider.useLoader('$translatePartialLoader', {
        urlTemplate: 'assets/i18n/{part}/{lang}.json'
    });

    $translatePartialLoaderProvider.addPart('myApp');
}

并在您的karma.conf.js中排除该文件:

代码语言:javascript
复制
        files: [
        'bower_components/angular/angular.js',
        'bower_components/angular-mocks/angular-mocks.js',
        //...
        'bower_components/angular-translate/angular-translate.js',
        'bower_components/angular-translate-loader-partial/angular-translate-loader-partial.js',
        'app/**/*.mdl.js',
        'app/**/*.js'
    ],

    exclude: [
        'app/app-i18n-loader.js'
    ],

(注:答案已编辑为不需要哼唱/吞咽的解决方案)。

票数 15
EN

Stack Overflow用户

发布于 2015-12-16 03:47:54

我想要一个解决方案,

  1. ,这不是太麻烦的
  2. ,它不需要我更改我的实际应用程序代码,
  3. ,它不会干扰加载附加模块的能力
  4. ,最重要的是,它不需要我更改每一个测试。

<代码>G29

这就是我最终得到的结论:

代码语言:javascript
复制
// you need to load the 3rd party module first
beforeEach(module('pascalprecht.translate'));
// overwrite useStaticFilesLoader to get rid of request to translation file
beforeEach(module(function ($translateProvider) {
    $translateProvider.useStaticFilesLoader = function () {
    };
}));

假设您的单元测试不需要实际的翻译,这将非常有效。只需将beforeEach放在全局级别上,最好放在测试文件夹内它自己的文件中。然后,它将在所有其他测试之前执行。

票数 12
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18876290

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档