在 Angular 7 中使用 Jest 进行测试时缺少 Kendo Intl Service 的语言环境信息

Posted

技术标签:

【中文标题】在 Angular 7 中使用 Jest 进行测试时缺少 Kendo Intl Service 的语言环境信息【英文标题】:Missing locale info for Kendo Intl Service when testing with Jest in Angular 7 【发布时间】:2019-09-25 01:33:10 【问题描述】:

我对处理区域设置格式的非常具体的数字组件进行了多次测试。 Karma 的测试很好,但是一旦我们将其更改为 Jest,就会开始出现此错误:

NoLocale: Missing locale info for 'de-DE' Solution: http://www.telerik.com/kendo-angular-ui/components/internationalization/troubleshooting/#toc-no-locale

我尝试了所附链接中的所有建议,但没有一个成功。

IntlService 使用 en-US 语言环境 ID 进行初始化,因此我为每个测试更改了它,具体取决于我想要断言的格式(de-DEen-GB)。

这些是component.spec.ts中的测试示例:

numeric-textbox.component.spec.ts

import  async, ComponentFixture, TestBed  from '@angular/core/testing';
import  NumericTextBoxComponent  from './numeric-textbox.component';
import  FormsModule  from '@angular/forms';
import  CldrIntlService, IntlModule, load  from '@progress/kendo-angular-intl';

describe('NumericTextBoxComponent', () => 
  let component: NumericTextBoxComponent;
  let fixture: ComponentFixture<NumericTextBoxComponent>;

  beforeEach(async(() => 
    TestBed.configureTestingModule(
      imports: [ FormsModule, IntlModule ],
      declarations: [ NumericTextBoxComponent ],
    )
    .compileComponents();
  ));

  beforeEach(() => 
    fixture = TestBed.createComponent(NumericTextBoxComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  );

  it('should create', () => 
    expect(component).toBeTruthy();
  );

  it('User writes valid numbers with German/International notation', () => 
    component.format = 'n2';
    (<CldrIntlService>component.intlService).localeId = 'de-DE';
    fixture.detectChanges();
      const displayValueInput: htmlInputElement = fixture.debugElement.nativeElement.querySelector('input');

  // absolute integer
  displayValueInput.value = '123456789';
  displayValueInput.dispatchEvent(new Event('input'));
  displayValueInput.dispatchEvent(new Event('focusout'));
  expect(component.inputValue).toBe('123456789');
  expect(component.displayValue).toBe('123.456.789,00');
);

it('displays the correct format when the control is created in english context', () => 
    component.format = 'n2';
    (<CldrIntlService>component.intlService).localeId = 'en-GB';
    fixture.detectChanges();
      const displayValueInput: HTMLInputElement = fixture.debugElement.nativeElement.querySelector('input');
      displayValueInput.value = '123456789.12';
      displayValueInput.dispatchEvent(new Event('input'));
      displayValueInput.dispatchEvent(new Event('focusout'));
      expect(component.inputValue).toBe('123456789.12');
      expect(component.displayValue).toBe('123,456,789.12');
  );

罕见的是“en-GB”语言环境被 Intl Service 识别(因此测试运行良好),但“de-DE”不是。

我的问题是:如何将de-DE的语言环境信息导入到测试环境中,以便Intl Service动态识别?

2019 年 5 月 10 日更新

fixture.whenStable().then(()=&gt; ) 导致测试错误处理出现问题,因此已将其删除。


作为附加信息,focusout 事件触发组件中的以下方法:

numeric-textbox.component.ts

onFocusOut(first: boolean = false): void 
      console.log("onFocusOut");
        if (this.isReadOnly && !first && !this.isFocusIn)  return; 
        this.isFocusIn = false;
        // save the temporal the editable display value into the inputValue.
        // if the escape key was pressed, then we undo the actual displayValue to the lastInputValue.
        this.inputValue = !this.wasEscapePressed ? this.displayValue : this.lastInputValue;
        this.wasEscapePressed = false;
        // update the readable display value with the absolute value of the input value (or zero if it is null, zero or empty).
        this.displayValue = this.formatDisplayValue(this.inputValue);
    

formatDisplayValue(input: string): string 
        // single signs, nulls, empty and zeros are shown as zero
        if (this.checkNullZeroOrEmpty(input) || this.isSignOnly(input)) 
            input = NumericTextBoxComponent.ZERO;
         else if (this.IsPositiveValue(input) && input[0] === NumericTextBoxComponent.PLUS_SIGN) 
            // positive signs at the beginning are trim
            input = input.replace(NumericTextBoxComponent.PLUS_SIGN, '');
        

        // display value are always the absolute value
        const numberValue = Math.abs(this.getNumberValue(input));

        // finally return the number formatted based in the locale. 
        return this.intlService.formatNumber(numberValue, this.format);
    

因此,当我将焦点移出输入 HTML 元素时,显示值的格式取决于区域设置。

【问题讨论】:

【参考方案1】:

我建议您尝试按照loading additional locale data 章节中链接到的文档中的说明导入它。由于您没有提到您加载了其他语言环境,我假设您根本没有这样做。否则,请提供您如何加载它们的其他信息。

对于 de locale,您需要添加以下导入。

// Load all required data for the de locale
import '@progress/kendo-angular-intl/locales/de/all';

【讨论】:

嗨@AlesD。导入此引用的开玩笑配置似乎存在问题。当我尝试这个解决方案时,我以为我之前忽略了。顺便说一句,感谢您的帮助。 你是怎么导入的?尝试在setupJest.ts 文件中添加导入。 我试过了,但它启动了同样的笑话配置错误。现在我实现了测试,避免语言更改并假设这确实有效,但我很好奇intlService 是如何设置的。

以上是关于在 Angular 7 中使用 Jest 进行测试时缺少 Kendo Intl Service 的语言环境信息的主要内容,如果未能解决你的问题,请参考以下文章

AG-Grid gridReady 未在使用 Angular 和 Jest 的测试中调用

在 sonarqube 中使用 jest 和旁观者覆盖组件方法的 Angular 打字稿测试

前端angular基础测试篇

Jest 单元测试中的 Angular 循环依赖问题

Angular + Jest:无法解析 AppComponent 的所有参数:(?)

使用 Jest 测试 Angular 时出现“意外的令牌导入”