У меня проблема с модульным тестированием следующего компонента Angular 9:
export class BirdsDetailComponent implements OnInit {
...
constructor(private service: BirdsService
, private flickr: FlickrService
, private route: ActivatedRoute
, private location: Location
, private router: Router) {
route.params.subscribe(_ => {
this.route.paramMap.subscribe(pmap => this.getData(+pmap.get('id')));
});
}
ngOnInit() {}
getData(id: number): void { ... }
В отличие от других знакомых мне компонентов, этот компонент инициирует извлечение данных из конструктора.
У меня проблема (я думаю) с настройкой параметра маршрута. Я пробовал ряд способов настройки активированного маршрута макета / заглушки. Включая тот, который находится в этой настройке в Angular документах .
describe('BirdsDetailComponent', () => {
let component: BirdsDetailComponent;
let fixture: ComponentFixture<BirdsDetailComponent>;
let activatedRoute: ActivatedRouteStub;
beforeEach(() => {
activatedRoute = new ActivatedRouteStub();
});
let mockBirdsService;
let mockFlickrService;
// the `id` value is irrelevant because ignored by service stub
beforeEach(() => activatedRoute.setParamMap({ id: 99999 }));
beforeEach(async(() => {
const routerSpy = createRouterSpy();
function createRouterSpy() {
return jasmine.createSpyObj('Router', ['navigate']);
}
mockBirdsService = jasmine.createSpyObj(['getData']);
TestBed.configureTestingModule({
imports: [RouterTestingModule.withRoutes([])],
declarations: [BirdsDetailComponent],
providers: [
{ provide: BirdsService, useValue: mockBirdsService },
{ provide: FlickrService, useValue: mockFlickrService },
{ provide: Router, useValue: routerSpy },
{
provide: ActivatedRoute, useValue: ActivatedRouteStub
}
// {
// provide: ActivatedRoute,
// useValue: {
// params: of({ id: '123' })
// }
// }
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(BirdsDetailComponent);
component = fixture.componentInstance;
activatedRoute.setParamMap({ id: 1 });
});
it('should call getData', () => {
const conserveStatus = {
conservationStatusId: 1, conservationList: 'string',
conservationListColourCode: 'string', description: 'string', creationDate: 'Date | string',
lastUpdateDate: 'Date | string', birds: []
};
const bird = {
birdId: 1, class: 'string', order: 'string', family: 'string',
genus: 'string', species: 'string', englishName: 'string', populationSize: 'string',
btoStatusInBritain: 'string', thumbnailUrl: 'string', songUrl: 'string',
birderStatus: 'string', birdConservationStatus: conserveStatus,
internationalName: 'string', category: 'string', creationDate: 'Date | string',
lastUpdateDate: 'Date | string'
};
mockBirdsService.getData.and.returnValue(of(bird));
fixture.detectChanges();
// // Act or change
// component.getBird(1);
// // fixture.detectChanges();
// Assert
expect(mockBirdsService.getBird).toHaveBeenCalled();
});
});
Я также попробовал простую настройку активированного параметра маршрута, который вы можете увидеть в закомментированном код, подобный этому (и его разновидности):
{
provide: ActivatedRoute,
useValue: {
params: of({ id: '123' })
}
}
Что бы я ни пытался, мне кажется, что я столкнулся с ошибкой "Cannot read property" subscribe "undefined брошено". Может ли проблема быть связана с обнаружением изменений? Кто-нибудь может указать мне правильное направление?