【问题标题】:Angular fakeAsync test of promise resolution in ngOnInit()ngOnInit() 中 Promise 解析的 Angular fakeAsync 测试
【发布时间】:2019-02-18 06:59:17
【问题描述】:

出于某种原因,我的fakeAsync 测试无法解决简单的承诺。我创建了一个显示问题的最小示例(主要是ng-生成的样板文件)。

我的测试组件在其ngOnInit 方法中包含一个简单的直接承诺解析:

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-simple-test',
  templateUrl: './simple-test.component.html',
  styleUrls: ['./simple-test.component.scss']
})
export class SimpleTestComponent implements OnInit {

  constructor() { }

  message: string;

  ngOnInit() {
    Promise.resolve('hello').then((content: string) => this.message = content);
  }

}

我正在使用以下测试来测试这个承诺:

import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';

import { SimpleTestComponent } from './simple-test.component';

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

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ SimpleTestComponent ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(SimpleTestComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should display "hello"', fakeAsync(() => {
    tick();
    expect(component.message).toBe('hello');
  }));
});

但是测试失败了,这意味着在expect 的时候这个promise 没有得到解决,尽管通过tick() 强制解决了promise。

在测试开始时向component.ngOnInit() 添加另一个显式调用时,它可以工作。但这会导致ngOnInit() 被调用两次。据我所知,beforeEach() 中的fixture.detectChanges() 无论如何都应该照顾ngOnInit()

我错过了什么?为什么在tick() 期间没有解决承诺?

【问题讨论】:

    标签: angular typescript testing jasmine


    【解决方案1】:

    发现问题。 ng g componentbeforeEach(...) 函数中使用fixture.detectChanges() 生成测试,该函数位于fakeAsync 区域之外,因此tick() 无法解析promise。

    fixture.detectChanges() 移动到fakeAsync 区域可以解决我的问题:

      beforeEach(() => {
        fixture = TestBed.createComponent(SimpleTestComponent);
        component = fixture.componentInstance;
      });
    
      it('should display "hello"', fakeAsync(() => {
        fixture.detectChanges();
        tick();
        expect(component.message).toBe('hello');
      }));
    

    【讨论】:

      【解决方案2】:

      已编辑 您需要先调用component.ngOnInit(),然后调用tick(),然后再调用expect 方法。在每种测试方法中执行此操作,这对我的测试有效。

      代码sn-p

        beforeEach(() => {
          fixture = TestBed.createComponent(SimpleTestComponent);
          component = fixture.componentInstance;
        });
      
        it('should display "hello"', fakeAsync(() => {
          component.ngOnInit();
          tick();
          expect(component.message).toBe('hello');
        }));
      

      【讨论】:

      • 这将调用ngOnInit() 两次,因为fixture.detectChanges() 已经在beforeEach(...) 函数中调用了ngOnInit()。将fixture.detectChanges() 移至实际测试即可修复它,而无需两次调用ngOnInit()
      • 这应该是公认的答案 - detectChanges() 混淆了解决方案。除非你想测试模板,否则不应调用它 - 你应该使用嵌套描述来测试模板,你可以调用 @987654329 @
      猜你喜欢
      • 2018-04-10
      • 2017-07-28
      • 2020-08-08
      • 2020-02-12
      • 2017-08-15
      • 2016-05-25
      • 1970-01-01
      • 1970-01-01
      • 2021-06-22
      相关资源
      最近更新 更多