私は、コードの深いところで解決される多くの内部約束を持つアプリケーションのjasmine/karma/webpack単体テストを書いています。私は、角度の非同期、fixture.detectChangesとfixture.whenStableを使用したいと思います。angular 4.3.0非同期関数を実行した後にfixture.whenStableを呼び出します
概念の証明として、私は以下のシンプルだが非常に非同期のコンポーネントを作った。
import {Component} from "@angular/core";
import {Logger} from "../../utils/logger";
@Component({
selector: 'unit-test.html',
template: `
<div class="unit-test">
<h3>Unit Test Component</h3>
<h4>p1: {{p1}}</h4>
<h4>v1: {{v1}}</h4>
<h4>p2: {{p2}}</h4>
<h4>v2: {{v2}}</h4>
<h4>p3: {{p3}}</h4>
<h4>v3: {{v3}}</h4>
</div>`
})
export class UnitTestComponent {
p1: Promise<string>;
v1: string;
p2: Promise<string>;
v2: string;
p3: Promise<string>;
v3: string;
constructor() {
this.p1 = makeTimeoutPromise('value1', 2000);
Logger.warn('p1 created');
this.p1.then(data => {
this.v1 = data
});
}
method2() {
this.p2 = makeTimeoutPromise('value2', 2000);
this.p2.then(data => {
this.v2 = data
});
Logger.warn('p2 created');
}
method3() {
this.p3 = makeTimeoutPromise('value3', 2000);
this.p3.then(data => {
this.v3 = data
});
Logger.warn('p2 created');
}
}
function makeTimeoutPromise(result: string, timeout: number) {
return new Promise<string>((resolve, reject) => {
setTimeout(() => {
resolve(result);
Logger.warn(`resolved '${result}' after '${timeout}' seconds`);
}, timeout)
});
}
これをテストするには、非同期ブロックでコンポーネントを作成します。これは動作し、itブロックはコンストラクタの約束が解決された後に実行を開始します。
私はcomp.method2()を呼び出すと、2秒後に約束が解決されます。しかし....そして私が得られない部分があります... comp.method2()を呼び出した直後にfixture.isStable()を呼び出すとtrueが返されます。私は偽を期待していただろう。悪い... fixture.whenStable()はすぐに解決します。実際の方法の約束が解決されていないので、私はまだテストしたいという価値がありません。
import {UnitTestComponent} from './unit-test.component';
import {async, ComponentFixture, TestBed, tick} from '@angular/core/testing';
import {DebugElement} from '@angular/core';
describe('UnitTestComponent',() => {
let de: DebugElement;
let comp: UnitTestComponent;
let fixture: ComponentFixture<UnitTestComponent>;
let el: HTMLElement;
const startTime = Date.now();
beforeEach(async(() => {
console.log('time beforeEach.start', Date.now() - startTime);
const testbed = TestBed.configureTestingModule({
declarations:[UnitTestComponent],
imports: [],
providers: []
});
// testbed.compileComponents();
console.log('time beforeEach.initSsmpComponentLibModule', Date.now() - startTime);
fixture = TestBed.createComponent(UnitTestComponent);
comp = fixture.componentInstance;
de = fixture.debugElement;
console.log('time beforeEach.end', Date.now() - startTime);
}));
it('should create the component', async(() => {
// const x = new Promise<any>((resolve, reject)=>{
// setTimeout(()=>{
// console.log('right before exit', comp);
// fixture.detectChanges();
// resolve();
// }, 10000);
// });
console.log('time it.start', Date.now() - startTime, comp);
expect(comp).toBeDefined();
console.log('fixture.isStable() (1)', fixture.isStable());
comp.method2();
console.log('fixture.isStable() (2)', fixture.isStable());
fixture.whenStable()
.then(data=>{
fixture.detectChanges();
console.log('time after whenStable(1) resolves', Date.now() - startTime, comp);
fixture.detectChanges();
console.log('time after whenStable(1).detect changes completes', Date.now() - startTime, comp);
expect(comp.v2).toBe('value2');
comp.method3();
console.log('method3 called', Date.now() - startTime, comp);
fixture.detectChanges();
console.log('time after detectChanges (2)', Date.now() - startTime, comp);
fixture.whenStable()
.then(data=>{
fixture.detectChanges();
console.log('time after whenStable(3).then', Date.now() - startTime, comp);
expect(comp.v3).toBe('value3');
});
console.log('time after whenStable(3)', Date.now() - startTime, comp);
});
console.log('time after whenStable(2)', Date.now() - startTime, comp);
}));
});
コンソールログの出力は以下のとおりです。私は
fixture.isStable() (2) false
time after whenStable(2) >=4386 UnitTestComponent {p1: ZoneAwarePromise, v1: "value1", p2: ZoneAwarePromise}
を期待していたが)(comp.method2の明示的な知識なしの内部を
fixture.isStable() (2) true
time after whenStable(2) 2390 UnitTestComponent {p1: ZoneAwarePromise, v1: "value1", p2: ZoneAwarePromise}
time beforeEach.start 363
time beforeEach.initSsmpComponentLibModule 363
time beforeEach.end 387
time it.start 2386 UnitTestComponent {p1: ZoneAwarePromise, v1: "value1"}
fixture.isStable() (1) true
fixture.isStable() (2) true
time after whenStable(2) 2390 UnitTestComponent {p1: ZoneAwarePromise, v1: "value1", p2: ZoneAwarePromise}
time after whenStable(1) resolves 2393 time beforeEach.start 363
を得た、どのように私はすべての約束はメソッドから解決までの角度待ち時間を持つことができますit()メソッドの中で呼び出されますか?私はこれがfixture.whenStableの明白な役割だと思った。