У меня проблемы с настройкой моего углового теста для правильной работы. Конкретная проблема заключается в том, что мой шпион, похоже, не работает. Я новичок в Angular и пытаюсь понять, как писать тесты. Фоном является то, что это для моего первого приложения Angular (с использованием последней версии CLI, 7.x). Это простое слайд-шоу. Слайд-шоу работает нормально, но я просто пытаюсь заставить тесты работать.
Первая часть этого заключается в том, что приложение должно получить ссылку на JavaScript из window.location. Основываясь на предложениях по Stackoverflow и в других местах, я создал класс для переноса окна, чтобы его можно было протестировать. Вот как это выглядит в службе с именем windowobject.service.ts:
import { Injectable } from '@angular/core';
function getWindow (): any {
return window;
}
@Injectable({
providedIn: 'root'
})
export class WindowObjectService {
constructor() { }
get browserWindow(): any {
return getWindow();
}
}
Это отлично работает, но проблема заключается в том, что это проблема в тесте. Мой тест называется photos.component.spec.ts:
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { PhotosComponent } from './photos.component';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap' ;
import { WindowObjectService } from '../services/windowobject.service';
import { environment } from '../../environments/environment';
const expectedId = 916;
class MockWindowObjectService {
browserWindow(): any {
return { window: {
location: {
href: environment.baseUrl + '/angular/slideshow/index.html?id=' + expectedId
}
}
};
}
}
describe('PhotosComponent', () => {
let component: PhotosComponent;
let fixture: ComponentFixture<PhotosComponent>;
let windowService: MockWindowObjectService;
let windowSpy;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [ HttpClientTestingModule, NgbModule ],
declarations: [PhotosComponent],
providers: [ { provide: WindowObjectService, useClass: MockWindowObjectService } ]
})
.compileComponents().then(() => {
windowService = TestBed.get(WindowObjectService);
fixture = TestBed.createComponent(PhotosComponent);
component = fixture.componentInstance;
});
}));
it('should create', () => {
expect(component).toBeTruthy();
});
it('should call window object service', () => {
windowSpy = spyOn(windowService, 'browserWindow').and.callThrough();
expect(windowService.browserWindow).toHaveBeenCalled();
});
});
То, что я пытаюсь сделать здесь, - это смоделировать службу объекта окна и определить, что она была вызвана. Как только я получу подтверждение, что он был успешно вызван, следующий тест, который я хотел бы написать, должен подтвердить, что он возвращает проверенное значение. Я пробовал много разных конфигураций этого теста, это только последняя итерация, но, похоже, ничего не работает. Я получаю только одну ошибку, и речь идет о шпионе, которого не вызывают. Любые идеи, как это исправить и заставить работать шутку и шпиона?
Обновление, добавление photos.component.ts. При этом используется карусель ng-bootstrap & pagination для отображения слайд-шоу, в котором показано по одному изображению за раз, и на которое можно перемещаться либо с помощью стрелок карусели, либо с помощью компонента нумерации страниц. Идентификатор коллекции фотографий взят из значения строки запроса в URL.
import { Component, OnInit, ViewChild } from '@angular/core';
import { PhotosService } from '../services/photos.service';
import { IPhoto } from '../models/photo';
import { NgbCarousel, NgbCarouselConfig, NgbPaginationConfig } from '@ng-bootstrap/ng-bootstrap';
import { WindowObjectService } from '../services/windowobject.service';
@Component({
selector: 'app-photos',
templateUrl: './photos.component.html',
styleUrls: ['./photos.component.scss'],
providers: [NgbCarouselConfig, WindowObjectService]
})
export class PhotosComponent implements OnInit {
// reference to "photosCarousel"
@ViewChild('photosCarousel') photosCarousel: NgbCarousel;
private _photosService: any;
private _windowService: WindowObjectService;
errorMessage: string;
photos: IPhoto[] = new Array;
page = 1;
collectionSize: number;
tripReportId: string;
constructor(carouselConfig: NgbCarouselConfig, paginationConfig: NgbPaginationConfig, phototsService: PhotosService,
windowService: WindowObjectService) {
carouselConfig.showNavigationArrows = true;
carouselConfig.showNavigationIndicators = false;
carouselConfig.interval = 0; // Amount of time in milliseconds before next slide is shown.
carouselConfig.wrap = false;
paginationConfig.pageSize = 1;
paginationConfig.maxSize = 5;
paginationConfig.size = 'sm';
paginationConfig.boundaryLinks = false;
this._photosService = phototsService;
this._windowService = windowService;
}
ngOnInit() {
console.log('this._windowService.browserWindow.location.href', this._windowService.browserWindow.location.href);
this.tripReportId = this._windowService.browserWindow.location.href.split('?')[1].split('=')[1];
this._photosService.getPhotos(this.tripReportId).subscribe(
photos => {
this.photos = photos;
this.collectionSize = photos.length;
},
error => this.errorMessage = <any>error
);
this.collectionSize = this.photos.length;
}
pageChanged(pageNumber: number): void {
this.photosCarousel.select(pageNumber.toString());
}
public onSlide(slideData) {
this.page = slideData.current;
}
}