为什么我的异步Angular Jasmine单元测试不起作用?

时间:2017-06-16 12:00:19

标签: angular unit-testing jasmine

我正在尝试测试异步组件方法,我认为我正在使用Angular 4的异步测试功能,但它无法正常工作。我的问题是,当我运行测试时,不等待让Promise解决。似乎函数的异步性质导致超时被触发并且测试过早地退出。无论如何都会通过测试,因为expect()内的所有whenStable()语句都会被跳过。

如果我省略async()包装器函数并切换到传入done回调的Jasmine语法并在whenStable()块的末尾调用它,它可以正常工作。任何人都可以告诉我为什么它不适用于Angular async()包装器?

我的代码如下所示:

// my.component.ts
ngOnInit() {
  this.getResults().then((results) => {
    this.results = results;
  });
}

// My asynchronous function, which takes 1.5s to load results
getResults() {
  let promise = new Promise((resolve) => {
    setTimeout(() => {
      resolve('foo');
    }, 1500);
  })
  return promise;
}


// my.component.spec.ts (Angular async version which doesn't work)
it('should load results', async(() => {
  spyOn(component, 'getResults').and.returnValue(Promise.resolve('bar'));
  component.ngOnInit();

  fixture.whenStable().then(() => {
    // Everything in here gets skipped when I run the test
    fixture.detectChanges();
    // This should cause the test to fail, but it doesn't because it's not run in time
    expect(true).toBe(false)
  });
}));

// my.component.spec.ts (Jasmine version that works)
it('should load results', (done) => {
  spyOn(component, 'getResults').and.returnValue(Promise.resolve('bar'));
  component.ngOnInit();

  fixture.whenStable().then(() => {
    fixture.detectChanges();
    // This should fail and it does because the test works using Jasmine's "done" callback
    expect(true).toBe(false);
    done();
  });
});

2 个答案:

答案 0 :(得分:4)

感谢@ yurzui的Plunker,我确定我的问题是由我在fixture.detectChanges()方法中调用beforeEach()引起的:

beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [AppComponent],
    });

    fixture = TestBed.createComponent(AppComponent);

    component = fixture.componentInstance;

    // The following line is to blame! Removing it makes the test work correctly.
    fixture.detectChanges();
});

答案 1 :(得分:0)

我遇到了一些麻烦,我们通过使用beforeEach中的angular / testing异步函数解决了这个问题:

beforeEach(async(() => { // <-- use async
    TestBed.configureTestingModule({
        declarations: [AppComponent],
    });

    fixture = TestBed.createComponent(AppComponent);

    component = fixture.componentInstance;

    // The following line is to blame! Removing it makes the test work correctly.
    fixture.detectChanges();
}));

...如文档所述:https://angular.io/guide/testing#async-test-with-async