我无法配置Angular测试以使其正常工作。具体的问题是我的间谍似乎无法正常工作。我是Angular的新手,试图了解如何编写测试。背景是这是我的第一个Angular应用程序(使用CLI的最新版本7.x)。这是一个简单的幻灯片。幻灯片效果很好,但我只是想使测试生效。
第一部分是应用程序需要从JavaScript window.location获取href。根据有关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轮播和分页显示幻灯片演示,一次显示一张图像,并且可以使用轮播箭头或分页组件进行导航。图片集ID来自网址中的查询字符串值。
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;
}
}
答案 0 :(得分:0)
好的,这是我将您的代码放入此StackBlitz中时发现的。
fixture.detectChanges()
才能执行ngOnInit()。WindowObjectService
,因此无法在默认provider数组中用模拟代替。而是需要使用overrideComponent()
,如StackBlitz中所示。windowService.browserWindow
会导致问题,所以请使用设置的spy变量。PhotosService
进行一些数据模拟,以使您也从此开始。如您所见,测试现在通过了。我希望这会有所帮助。