typescript - (Kiểm thử đơn vị Angular) Làm thế nào để giả lập thuộc tính đầu vào trong Jasmine?
Hiện tại tôi đang cố gắng giả lập các thuộc tính đầu vào cho một bài kiểm tra đơn vị Angular. Thật không may, tôi không thể tiến xa hơn và liên tục nhận được thông báo lỗi sau:
TypeError: Không thể đọc thuộc tính 'data' của undefined
Mẫu HTML của tôi trông như thế này
<div class="container-fluid">
<div class="row">
<div class="col-12">
<plot [data]="graph.data" [layout]="graph.layout"></plot>
</div>
</div>
</div>
Component của tôi như thế này:
...
export class ChartComponent implements OnInit {
@Input() currentChart: Chart;
currentLocationData: any;
public graph = {
data: [
{
type: 'bar',
x: [1, 2, 3],
y: [10, 20, 30],
}
],
layout: {
title: 'A simple chart',
},
config: {
scrollZoom: true
}
};
...
}
Bài kiểm thử đơn vị của tôi trông rất cơ bản hiện tại, nhưng vẫn phát sinh lỗi đã đề cập:
describe('ChartComponent', () => {
let component: ChartComponent;
let fixture: ComponentFixture<ChartComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ChartComponent],
imports: [
// My imports
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ChartComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
Tôi đã thử nhiều cách khác nhau để giả lập thuộc tính dữ liệu và currentChart @Input.
Cách đúng để đạt được điều này và sửa bài kiểm tra đơn vị là gì?
Câu trả lời #1
Thuộc tính input hoạt động giống như bất kỳ biến nào. Trong beforeEach của bạn, bạn có thể gán nó một giá trị
beforeEach(() => {
fixture = TestBed.createComponent(ExplorerChartViewComponent);
component = fixture.componentInstance;
component.currentChart = someChart; // set input before first detectChanges
fixture.detectChanges();
});
Bạn có thể đọc thêm về điều này tại đây. Tôi thích phương pháp này hơn.
Với phương pháp ưa thích của tôi, bạn sẽ có một thành phần TestHost sẽ trông như sau
@Component({
selector: 'app-testhost-chart',
template: `<app-chart [currentChart]=chart></app-chart>`, // or whatever your Chart Component Selector is
})
export class TestHostComponent {
chart = new Chart();
}
Sau đó chuyển sang tạo máy chủ kiểm tra mới.
declarations: [ChartComponent, TestHostComponent ],
...
beforeEach(() => {
fixture = TestBed.createComponent(TestHostComponent );
component = fixture.debugElement.children[0].componentInstance;
fixture.detectChanges();
});
Tuy nhiên, tôi nghĩ tôi thấy hai vấn đề khác mà bạn có thể gặp phải. Đặc biệt là vì bạn đang gán biểu đồ
- Bạn đang đặt
declarations: [ChartComponent],nhưng lại tạofixture=TestBed.createComponent(ExplorerChartViewComponent);Tôi nghĩ nên làTestBed.createComponent(ChartComponent), trừ khi đó là vấn đề sao chép/dán. - HTML của bạn có
<plot [data]="graph.data" [layout]="graph.layout"></plot>điều này cho thấy một thành phần plot mà bạn chưa khai báo. Bạn sẽ cần khai báo một thành phần cho plot. Tôi đề nghị làm một cách rất tương tự với TestHostComponent nhưng một phiên bản có tất cả các thuộc tính công khai giống như PlotComponent thực của bạn, như vậy bạn sẽ không mang toàn bộ chức năng và các phụ thuộc của PlotComponent vào bài kiểm tra đơn vị cho ChartComponent.
