Meskipun jawaban pilihan tertinggi berfungsi, namun tidak menunjukkan praktik pengujian yang baik, jadi saya pikir saya akan memperluas jawaban Günter dengan beberapa contoh praktis.
Bayangkan kita memiliki komponen sederhana berikut:
@Component({
selector: 'my-demo',
template: `
<button (click)="buttonClicked()">Click Me!</button>
`
})
export class DemoComponent {
@Output() clicked = new EventEmitter<string>();
constructor() { }
buttonClicked(): void {
this.clicked.emit('clicked!');
}
}
Komponen adalah sistem yang diuji, memata-matai bagian-bagiannya yang merusak enkapsulasi. Tes komponen sudut seharusnya hanya mengetahui tiga hal:
- DOM (diakses melalui mis.
fixture.nativeElement.querySelector
);
- Nama
@Input
s dan @Output
s; dan
- Layanan kolaborasi (disuntikkan melalui sistem DI).
Apa pun yang melibatkan pemanggilan metode secara langsung pada instans atau memata-matai bagian komponen terlalu erat digabungkan dengan penerapan, dan akan menambah gesekan pada refactoring - uji ganda sebaiknya hanya digunakan untuk kolaborator. Dalam hal ini, karena kita tidak memiliki kolaborator, kita seharusnya tidak perlu setiap mengolok-olok, mata-mata atau ganda tes lainnya.
Salah satu cara untuk mengujinya adalah dengan berlangganan langsung ke emitor, lalu menjalankan tindakan klik (lihat Komponen dengan masukan dan keluaran ):
describe('DemoComponent', () => {
let component: DemoComponent;
let fixture: ComponentFixture<DemoComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ DemoComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(DemoComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should emit when clicked', () => {
let emitted: string;
component.clicked.subscribe((event: string) => {
emitted = event;
});
fixture.nativeElement.querySelector('button').click();
expect(emitted).toBe('clicked!');
});
});
Meskipun ini berinteraksi langsung dengan instance komponen, nama dari @Output
adalah bagian dari API publik, jadi tidak terlalu terkait erat.
Atau, Anda dapat membuat host pengujian sederhana (lihat Komponen di dalam host pengujian ) dan benar-benar memasang komponen Anda:
@Component({
selector: 'test-host',
template: `
<my-demo (clicked)="onClicked($event)"></my-demo>
`
})
class TestHostComponent {
lastClick = '';
onClicked(value: string): void {
this.lastClick = value;
}
}
kemudian uji komponen dalam konteks:
describe('DemoComponent', () => {
let component: TestHostComponent;
let fixture: ComponentFixture<TestHostComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ TestHostComponent, DemoComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(TestHostComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should emit when clicked', () => {
fixture.nativeElement.querySelector('button').click();
expect(component.lastClick).toBe('clicked!');
});
});
Ini componentInstance
adalah host pengujian , jadi kami dapat yakin bahwa kami tidak terlalu digabungkan dengan komponen yang sebenarnya kami uji.