在angularJS的karma jasmine单元测试中更改区域设置



我正试图在AngularJS的Jasmine单元测试中使用angular dynamic local来更改区域设置(通过Karma运行)。

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

第二次测试失败:

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

区域设置从未更改。控制台指示404错误:

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

在浏览器中运行应用程序时可以识别的URL路径,在运行Karma时似乎无法识别。

我错过了什么?

最终解决。我们这里有几件事要做。

  1. 我没有在karma.conf.js中加载区域设置。我之前曾尝试在karma.coff.jsr-ca区域设置一次,但我删除了这一行,因为它破坏了默认(US)测试。事实证明,我还需要加载en-us区域设置(然后在beforeEach中重置区域设置,如我们将在#4中看到的)。

    files: [
        ...
        'bower_components/angular-i18n/angular-locale_en-us.js',
        'bower_components/angular-i18n/angular-locale_fr-ca.js',
        ...
    ],
    
  2. 正如martinoss正确指出的那样,我需要更改区域设置位置模式。在货币过滤器的直接测试中,这很困难,因为没有任何模块可以更改tmhDynamicLocale的提供程序。在我的现实世界中,这不是一个问题,因为我正在测试一个包装货币过滤器的自定义过滤器。为了这篇文章的目的,我创建了一个脑死亡包装过滤器:

    (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. 前两项解决了404问题。但是加拿大法语地区在$符号之前指定了一个空格,所以我将断言更改为expect(currencyFilter(50.17)).toBe("50,17 $");
      但这也没用。货币过滤器实际上插入了一个非中断空格。因此正确的断言是expect(currencyFilter(50.17)).toBe("50,17u00A0$");

    2. tmhDynamicLocale.set是异步的。此外,我们需要在每次测试之前将区域设置重置为默认值(US)。以下是完整的规范(使用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,17u00A0$");
              });
          });
      });
      

这是因为angular dynamic locale在调用set方法时正在加载区域设置脚本(在您的情况下是fr-ca)。您添加到karma.conf.js的文件由/base/angular/…提供。。。,这就是你得到404分的原因。

您可以做的是更改thmDynamicLocaleProvider的localeProviderPattern以包括基本路径(在模块配置中):

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

最新更新