How do unit test with angular-translate

后端 未结 11 1855
死守一世寂寞
死守一世寂寞 2020-12-08 09:38

I have uses angular translate from here (http://pascalprecht.github.io/angular-translate/) and it\'s just work fine, but it break my controller\'s unit test whith Error:

相关标签:
11条回答
  • 2020-12-08 09:54

    None of the solutions worked for me but I came with these solutions:

    1) If you need to use scope.$apply(), or should deal with states in your test (after the $apply() the 2nd approach won't work), override your app's translations with the $translateProvider.translations() method, using a plugin to load JSON files

    beforeEach(module(function ($translateProvider) {
        $translateProvider.translations('en', readJSON('scripts/i18n/locale-en.json'));
    }));
    

    2) If your tested controller depends on the $translate service you can use a plugin to load JSON files and combine it with $httpBackend to load your locale file when angular-translate requests it.

    beforeEach(inject(function (_$httpBackend_) {
        $httpBackend = _$httpBackend_;
    
        $httpBackend.whenGET('scripts/i18n/locale-en.json').respond(readJSON('scripts/i18n/locale-en.json'));
        $httpBackend.flush();
    })));
    

    Note this should be below your beforeEach(module('myApp')); or you will get an $injector error.

    0 讨论(0)
  • 2020-12-08 09:54

    The 2016 answer for this is to preprocess your json into your tests and properly test translations work on your directives.

    I use karma-ng-json2js-preprocessor. Follow all the steps to setup your karma.conf then in your test file, prepend the relevant file as a module, then set that information in $translateProvider.

    beforeEach(module('myApp', '/l10n/english-translation.json'));
    
    // Mock translations for this template
    beforeEach(module(function($translateProvider, englishTranslation) {
        $translateProvider.translations('en_us', englishTranslation);
        $translateProvider.useSanitizeValueStrategy(null);
        $translateProvider.preferredLanguage('en_us');
    }));
    

    Note according to the plugin, it uses your filename to generate a camelcased module name. You can play with the function inside the module's /lib but basically it remove all dashes but KEEPS underscores in a camelCase. So en_us becomes En_us.

    You'll also need to tell your test that it is expecting that file as a GEt.

        $httpBackend.expect('GET', '/l10n/english-translation.json').respond(200);
    
    0 讨论(0)
  • 2020-12-08 09:59

    Late to the table with this, but I got round this by specifying that Karma simply serve the files as per this entry in karma.conf.js:

    files: [
        ...
        {pattern: 'scripts/i18n/*.json', included: false, served: true},
        ...
    ]
    
    0 讨论(0)
  • 2020-12-08 10:00

    We took the approach of ignoring the translation loader in unit tests, rather than being forced to modify each of the spec files.

    One way to do it could be by separating the loader configuration to a separate file and then exclude it in karma.

    So for example you can create a file app-i18n-loader.js (all other module configurations takes place in a different file):

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

    And in your karma.conf.js exclude the file:

            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'
        ],
    

    (Note: Answer edited to a solution that does not require grunt/gulp).

    0 讨论(0)
  • 2020-12-08 10:00

    Please have a look at https://github.com/PascalPrecht/angular-translate/blob/master/test/unit/service/loader-static-files.spec.js as a reference.

    In general, I would recommend using a standard translation loader for unit tests (without the hassle of http loadings) which means you can provide the labels with $translateProvider.translations(). Why? Because you do not have to test the remote loading functionality which is part of angular-translate project.

    0 讨论(0)
  • 2020-12-08 10:03

    I wanted a solution,

    1. which was not too hacky
    2. which didn't require me to change my actual application code,
    3. which wouldn't interfere with the ability to load additional modules
    4. and most importantly which wouldn't require me to change every single test.

    This is what I ended up with:

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

    Assuming you don't need the actual translations for your unit tests, this works great. Just put the beforeEach on a global level, preferably in it's own file inside the test folder. It will be executed before every other test then.

    0 讨论(0)
提交回复
热议问题