将主题添加到服务并在组件中订阅之后,对该组件的所有测试均因
失败Cannot read property 'unsubscribe' of undefined
我想知道
-为什么该组件的 all 测试失败并且
-如何测试主体,其next()方法及其订阅,如以下Angular 8中所述。
组件:
export class TrackerComponent implements OnInit, OnDestroy {
trackSubscription: Subscription;
constructor(private trackerService: TrackerService) { }
ngOnInit() {
this.trackSubscription = this.trackerService.trackSubject.subscribe((state) => {
console.log(state);
});
}
startTracking() { // called by clicking html button
this.trackerService.start();
}
ngOnDestroy() {
this.trackSubscription.unsubscribe();
}
}
服务:
export class TrackerService {
trackSubject = new Subject<boolean>();
start() {
// do stuff
this.trackSubject.next(true);
}
}
测试:
describe('TrackerComponent', () => {
let component: TrackerComponent;
let fixture: ComponentFixture<TrackerComponent>;
let trackerService: jasmine.SpyObj<TrackerService>;
// helper function
const el = (selector) => fixture.nativeElement.querySelector(selector);
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [TrackerComponent],
providers: [
{ provide: TrackerService, useFactory: () => spyOnClass(TrackerService) }
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(TrackerComponent);
component = fixture.componentInstance;
trackerService = TestBed.get(TrackerService);
fixture.detectChanges();
});
// it should show a start button
it('should show a start button', () => {
expect(el('[data-test="start-btn"]')).toBeTruthy();
});
it('should call tracker service when start button clicked', async(() => {
el('[data-test="start-btn"]').click();
fixture.whenStable().then(() => {
expect(trackerService.startTracking).toHaveBeenCalled();
});
}));
});
答案 0 :(得分:1)
这是因为订阅没有发生过一次。我们可以通过添加支票来克服。
ngOnDestroy() {
if(this.trackSubscription){
this.trackSubscription.unsubscribe();
}
}
如果问题出在运行测试用例时
it('calls ngOnDestroy method', () => {
component.trackSubscription= new Subscription();
spyOn(component.trackSubscription, 'unsubscribe');
component.ngOnDestroy();
expect(component.trackSubscription.unsubscribe).toHaveBeenCalled();
});
希望有帮助!
答案 1 :(得分:0)
在测试中通过测试后,我的测试通过了-但由于我是单元测试的新手,所以不确定是否有意义。
在之前的中,我创建主题和订阅:
component.trackSubscription = new Subscription();
trackerService.trackSubject = new Subject<boolean>();
然后是实际测试:
it('should subscribe trackSubscription to service subject', () => {
component.trackSubscription = trackerService.trackSubject.subscribe();
spyOn(trackerService.trackSubject, 'subscribe');
component.ngOnInit();
expect(trackerService.trackSubject.subscribe).toHaveBeenCalled();
});
it('unsubscribes the trackSubscription', () => {
spyOn(component.trackSubscription, 'unsubscribe');
component.ngOnDestroy();
expect(component.trackSubscription.unsubscribe).toHaveBeenCalled();
});
编辑:实际上只是在每个主题都通过所有测试通过之前声明主题和订阅,但是我想也测试(un)subscribe方法并没有什么害处。