Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 角度/卡玛单元测试错误“;1个计时器仍在队列中“;_Angular_Typescript_Unit Testing_Karma Jasmine - Fatal编程技术网

Angular 角度/卡玛单元测试错误“;1个计时器仍在队列中“;

Angular 角度/卡玛单元测试错误“;1个计时器仍在队列中“;,angular,typescript,unit-testing,karma-jasmine,Angular,Typescript,Unit Testing,Karma Jasmine,这不是我第一次遇到“1个计时器仍在队列中”,但通常我会找到一些方法使用tick()或detectChanges()等来摆脱它 在我尝试测试我知道应该引发异常的条件之前,下面的测试一直运行良好: it('should be able to change case', fakeAsync(() => { expect(component).toBeTruthy(); fixture.whenStable().then(fakeAsync(() => {

这不是我第一次遇到
“1个计时器仍在队列中”
,但通常我会找到一些方法使用
tick()
detectChanges()
等来摆脱它

在我尝试测试我知道应该引发异常的条件之前,下面的测试一直运行良好:

  it('should be able to change case', fakeAsync(() => {
    expect(component).toBeTruthy();

    fixture.whenStable().then(fakeAsync(() => {
      component.case = 'lower';
      fixture.autoDetectChanges();
      tick(500);
      const input = fixture.nativeElement.querySelector('input') as HTMLInputElement;
      typeInElement('abcDEF', input);
      fixture.autoDetectChanges();
      tick(500);
      expect(component.text).toEqual('abcdef');

      component.case = 'upper';
      fixture.autoDetectChanges();
      tick(500);
      typeInElement('abcDEF', input);
      fixture.autoDetectChanges();
      tick(500);
      expect(component.text).toEqual('ABCDEF');

      // Everything above works fine. Here's where the trouble begins
      expect(() => {
        component.case = 'foo';
        fixture.autoDetectChanges();
        tick(500);
      }).toThrowError(/Invalid case attribute/);
    }));
  }));
我正在测试的是一个角度组件,它是一个围绕着材料输入字段的包装。该组件有许多可选属性,其中大多数只是传递通用输入字段特性的属性,但也有一些自定义属性,就像我在上面测试的用于大写/小写转换的属性一样

大小写
属性的可接受值为
上限
下限
混合
(将空字符串、null或未定义视为
混合
)。组件应该为其他任何内容引发异常。显然是这样,测试成功了,但随着我的成功:

ERROR: 'Unhandled Promise rejection:', '1 timer(s) still in the queue.', '; Zone:', 'ProxyZone', '; Task:', 'Promise.then', '; Value:', Error: 1 timer(s) still in the queue.
Error: 1 timer(s) still in the queue.
   ...
有谁能告诉我我可能做错了什么,或者是一个好方法来清除那些挥之不去的计时器

免责声明:我在寻找Karma单元测试帮助时遇到的一个大问题是,即使我明确搜索“Karma”,我也会找到Pr0tractor、Pr0tractor和更多Pr0tractor的答案。这不是骗子!(故意拼错了零,因此无法获得搜索匹配。)

更新:我可以这样解决我的问题:

      expect(() => {
        component.inputComp.case = 'foo';
      }).toThrowError(/Invalid camp-input case attribute/);

这不如通过测试组件模板中的HTML属性分配(坏)值好,因为我只是将值直接强制到组件属性本身的setter中,但直到有更好的解决方案为止。

我最近遇到了同样的问题-为了解决这个问题,我调用了
discardoperiodictasks()
-在我的
it
功能结束时,从
@angular/core/testing
,然后我的测试通过了

在这种情况下,您可能希望在最终的
expect

 it('should be able to change case', fakeAsync(() => {
    expect(component).toBeTruthy();

    fixture.whenStable().then(fakeAsync(() => {
      component.case = 'lower';
      fixture.autoDetectChanges();
      tick(500);
      const input = fixture.nativeElement.querySelector('input') as HTMLInputElement;
      typeInElement('abcDEF', input);
      fixture.autoDetectChanges();
      tick(500);
      expect(component.text).toEqual('abcdef');

      component.case = 'upper';
      fixture.autoDetectChanges();
      tick(500);
      typeInElement('abcDEF', input);
      fixture.autoDetectChanges();
      tick(500);
      expect(component.text).toEqual('ABCDEF');

      discardPeriodicTasks() <-------------------- try here

      // Everything above works fine. Here's where the trouble begins
      expect(() => {
        component.case = 'foo';
        fixture.autoDetectChanges();
        tick(500);
      }).toThrowError(/Invalid case attribute/);
      
    }));
it('应该能够改变大小写'),fakeAsync(()=>{
expect(component.toBeTruthy();
fixture.whenStable()然后(fakeAsync(()=>{
component.case='lower';
fixture.autoDetectChanges();
勾选(500);
const input=fixture.nativeElement.querySelector('input')作为HTMLInputElement;
类型输入('abcDEF',输入);
fixture.autoDetectChanges();
勾选(500);
expect(component.text).toEqual('abcdef');
component.case='upper';
fixture.autoDetectChanges();
勾选(500);
类型输入('abcDEF',输入);
fixture.autoDetectChanges();
勾选(500);
expect(component.text).toEqual('ABCDEF');

discardPeriodicTasks()我也遇到过类似的问题。解决方法是函数使用

从'@angular/core/testing'导入{fakeAsync,flush};
它('testsomething',fakeAsync(()=>{
// ...
冲洗();
}));

OK,除了测试问题之外,为什么不将属性定义为枚举或允许字符串的并集,以便在编译时捕获它?实际上,它是这样定义的(
type InputCase='lower'|'mixed'|'upper';
),但通过HTML分配的属性无法可靠地进行类型检查。顺便问一下,您对我的免责声明有什么问题?此外,通过使用检查有效性的setter,值也可以不区分大小写。这是Angular的一个非常重要的功能(而不是mis功能)您可以创建自定义组件,然后让用户在HTML中按照自己的意愿使用这些组件,如
。至于引发异常与在控制台警告下悄然失败,这两种方法都有优缺点,在这种情况下,无论如何这不是我的要求。我已经从之前遇到此问题的项目中转移,但我应该将此答案添加到书签中,以便在下次我继续进行任何角度单元测试时尝试。今天早上它确实让我省去了很多头痛,所以我想与大家分享。Bestflush()作为单元测试的最后一条指令为我工作。不幸的是,DiscardPeriodictTasks()无效:-)仅供参考:在处理按钮点击并要求说明其副作用时,我偶然发现了fakeAsync的一个合法用例!使用tick()的要求改变了它。.在“async”块中,等效的设置超时(()=>{},0),但同时使用fixture.whenStable()更像是一个代码膨胀。。