Хоча відповіді з найбільшою кількістю голосів працюють, вони не демонструють належної практики тестування, тому я подумав, що докладу більше уваги до відповіді Гюнтера декількох практичних прикладах.
Уявімо, що у нас є такий простий компонент:
@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!');
}
}
Компонент - це система, що випробовується, шпигування за частинами розриває капсулювання. Тести кутових компонентів повинні знати лише про три речі:
- DOM (доступ через, наприклад
fixture.nativeElement.querySelector
);
- Назви
@Input
s та@Output
s; і
- Послуги, що співпрацюють (вводяться через систему DI).
Все, що передбачає безпосередній виклик методів на екземплярі або шпигунство за частинами компонента, занадто тісно пов’язане з реалізацією, і це додасть тертя рефакторингу - тестові подвійні слід використовувати лише для співавторів. У цьому випадку, оскільки у нас немає співавторів, нам не потрібно мати жодних насмішок, шпигунів чи інших тестових дублів.
Один із способів перевірити це - підписатися безпосередньо на випромінювач, а потім викликати дію клацання (див. Компонент із входами та виходами ):
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!');
});
});
Хоча це взаємодіє безпосередньо з екземпляром компонента, ім'я @Output
є частиною загальнодоступного API, тому воно не надто тісно пов'язане.
Крім того, ви можете створити простий тестовий хост (див. Компонент всередині тестового хосту ) і фактично змонтувати свій компонент:
@Component({
selector: 'test-host',
template: `
<my-demo (clicked)="onClicked($event)"></my-demo>
`
})
class TestHostComponent {
lastClick = '';
onClicked(value: string): void {
this.lastClick = value;
}
}
потім протестуйте компонент у контексті:
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!');
});
});
componentInstance
Ось тест господар , так що ми можемо бути впевнені в тому, що ми не дуже пов'язані з компонентом , ми на самому ділі тестування.