Changing locale in karma-jasmine unit test for angularJS

纵饮孤独 提交于 2019-12-10 10:06:10

问题


I am attempting to change locale in a jasmine unit test for angularJS (being run through Karma) using angular-dynamic-local.

describe('currency filter', function () {
    var currencyFilter;
    var tmhDynamicLocale;

    beforeEach(function () {
        module('tmh.dynamicLocale');

        inject(function ($injector) {
            var $filter = $injector.get('$filter');
            currencyFilter = $filter('currency');
            tmhDynamicLocale = $injector.get('tmhDynamicLocale');
        });
    });

    it('formats US currency in standard form', function () {
        expect(currencyFilter(50.17)).toBe("$50.17");
    });

    it('formats French Canadian value with $ at end and comma for decimal', function () {
        tmhDynamicLocale.set('fr-ca');
        expect(currencyFilter(50.17)).toBe("50,17$");
    });
});

The second test fails:

Expected '$50.17' to be '50,17$'.

The locale was never changed. The console indicates a 404 error:

WARN [web-server]: 404: /angular/i18n/angular-locale_fr-ca.js

It appears that this URL path, which is recognized when running the application in the browser, is not recognized when running through Karma.

What am I missing?


回答1:


Finally solved. We have several things going on here.

  1. I was not loading the locale in karma.conf.js. I had tried loading the fr-ca locale in karma.conf.js once before, but I had deleted the line because it was breaking the default (US) test. Turns out that I need to load the en-us locale as well (and then reset the locale in beforeEach as we will see in #4).

    files: [
        ...
        'bower_components/angular-i18n/angular-locale_en-us.js',
        'bower_components/angular-i18n/angular-locale_fr-ca.js',
        ...
    ],
    
  2. As martinoss correctly stated, I needed to change the locale location pattern. In a direct test of the currency filter, this is difficult, since there is no module on which to change tmhDynamicLocale's provider. In my real-world situation, this is not an issue, since I am testing a custom filter that is wrapping the currency filter. For the purposes of this post, I created a brain-dead wrapper filter:

    (function() {
        angular
            .module('currencyFilterWrapper', [
                'tmh.dynamicLocale'
            ])
            .config(['tmhDynamicLocaleProvider', function(tmhDynamicLocaleProvider) {
                tmhDynamicLocaleProvider.localeLocationPattern('base/bower_components/angular-i18n/angular-locale_{{locale}}.js');
    }])
            .filter('doCurrency', doCurrency)
        ;
    
        function doCurrency($filter) {
            return function(input) {
                return $filter('currency')(input);
            }
        }
    })();
    
    1. These first two items addressed the 404 problem. But the French-Canadian locale specifies a space before the $-sign, so I changed the assertion to expect(currencyFilter(50.17)).toBe("50,17 $");
      But that didn't work either. The currency filter is actually inserting a non-breaking space. So the correct assertion is expect(currencyFilter(50.17)).toBe("50,17\u00A0$");

    2. tmhDynamicLocale.set is asynchronous. Also, we need to reset the locale to the default (US) before each test. So here is the complete spec (using Jasmine 1.3):

      describe('currency filter', function () {
          var currencyFilter;
          var tmhDynamicLocale;
      
          function setLocale(locale) {
              var localeSet;
      
              runs(function () {
                  tmhDynamicLocale.set(locale)
                      .then(function () {
                          localeSet = true;
                      });
              });
      
              waitsFor(function () {
                  return localeSet;
              }, 'setting locale', 100);
          }
      
          beforeEach(function () {
              module('currencyFilterWrapper');
              module('tmh.dynamicLocale');
      
              inject(function ($injector) {
                  var $filter = $injector.get('$filter');
                  currencyFilter = $filter('doCurrency');
                  tmhDynamicLocale = $injector.get('tmhDynamicLocale');
              });
      
              setLocale('en-us');
          });
      
          it('formats US currency in standard form', function () {
              expect(currencyFilter(50.17)).toBe("$50.17");
          });
      
          it('formats French Canadian value with $ at end and comma for decimal', function () {
              setLocale('fr-ca');
      
              runs(function () {
                  expect(currencyFilter(50.17)).toBe("50,17\u00A0$");
              });
          });
      });
      



回答2:


This is because angular-dynamic-locale is loading the locale script (fr-ca in your case) when calling the set-method. The files you add to your karma.conf.js are served from /base/angular/..., this is why you get a 404.

What you can do is to change the localeProviderPattern of thmDynamicLocaleProvider to include the base path (in the module configuration):

tmhDynamicLocaleProvider.localeLocationPattern('base/angular/i18n/angular-locale_{{locale}}.js');


来源:https://stackoverflow.com/questions/34358692/changing-locale-in-karma-jasmine-unit-test-for-angularjs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!