Mặc dù các câu trả lời được bình chọn cao nhất hoạt động, nhưng chúng không thể hiện các phương pháp kiểm tra tốt, vì vậy tôi nghĩ tôi sẽ mở rộng câu trả lời của Günter bằng một số ví dụ thực tế.
Hãy tưởng tượng chúng ta có một thành phần đơn giản sau:
@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!');
}
}
Thành phần là hệ thống đang được thử nghiệm, do thám các phần của nó sẽ phá vỡ tính đóng gói. Kiểm tra thành phần góc chỉ nên biết về ba điều:
- DOM (được truy cập thông qua ví dụ
fixture.nativeElement.querySelector
);
- Tên của
@Input
s và @Output
s; và
- Hợp tác dịch vụ (tiêm qua hệ thống DI).
Bất kỳ điều gì liên quan đến việc gọi trực tiếp các phương thức trên phiên bản hoặc theo dõi các phần của thành phần đều được kết hợp quá chặt chẽ với việc triển khai và sẽ gây thêm khó khăn cho việc tái cấu trúc - chỉ nên sử dụng bộ đôi thử nghiệm cho các cộng tác viên. Trong trường hợp này, vì chúng tôi không có cộng tác viên, nên chúng tôi không cần bất kỳ trò giễu cợt, gián điệp hoặc các bộ đôi thử nghiệm khác.
Một cách để kiểm tra điều này là bằng cách đăng ký trực tiếp với bộ phát, sau đó gọi hành động nhấp chuột (xem Thành phần với đầu vào và đầu ra ):
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!');
});
});
Mặc dù điều này tương tác trực tiếp với cá thể thành phần, tên của thành @Output
phần là một phần của API công khai, vì vậy nó không được kết hợp quá chặt chẽ.
Ngoài ra, bạn có thể tạo một máy chủ thử nghiệm đơn giản (xem Thành phần bên trong máy chủ thử nghiệm ) và thực sự gắn kết thành phần của bạn:
@Component({
selector: 'test-host',
template: `
<my-demo (clicked)="onClicked($event)"></my-demo>
`
})
class TestHostComponent {
lastClick = '';
onClicked(value: string): void {
this.lastClick = value;
}
}
sau đó kiểm tra thành phần trong ngữ cảnh:
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!');
});
});
Đây componentInstance
là máy chủ thử nghiệm , vì vậy chúng tôi có thể tự tin rằng chúng tôi không kết hợp quá nhiều với thành phần mà chúng tôi đang thực sự thử nghiệm.