Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 角度测试间谍没有被调用_Angular_Typescript_Unit Testing_Mocking_Karma Jasmine - Fatal编程技术网

Angular 角度测试间谍没有被调用

Angular 角度测试间谍没有被调用,angular,typescript,unit-testing,mocking,karma-jasmine,Angular,Typescript,Unit Testing,Mocking,Karma Jasmine,我在配置角度测试时遇到问题,无法正常工作。具体的问题是,我的间谍似乎没有工作。我对Angular是个新手,我试图理解如何编写测试。背景是这是我的第一个Angular应用程序(使用最新版本的CLI 7.x)。这是一个简单的幻灯片。幻灯片效果很好,但我只是想让测试正常进行 第一部分是应用程序需要从JavaScript window.location获取href。基于Stackoverflow和其他方面的建议,我创建了一个类来包装窗口,以便对其进行测试。下面是一个名为windowobject.serv

我在配置角度测试时遇到问题,无法正常工作。具体的问题是,我的间谍似乎没有工作。我对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();
  });

});
从'@angular/core/testing'导入{async,ComponentFixture,TestBed};
从'@angular/common/http/testing'导入{HttpClientTestingModule};
从“./photos.component”导入{PhotosComponent};
从'@ng bootstrap/ng bootstrap'导入{NgbModule};
从“../services/windowobject.service”导入{WindowObjectService};
从“../../environments/environment”导入{environment};
const expectedId=916;
类MockWindowObjectService{
browserWindow():任何{
返回{窗口:{
地点:{
href:environment.baseUrl+'/angular/slideshow/index.html?id='+expectedId
}
}
};
}
}
描述('PhotosComponent',()=>{
let组件:PhotosComponent;
let夹具:组件夹具;
让Windows服务:MockWindowObjectService;
让我们一起来吧;
beforeach(异步(()=>{
TestBed.configureTestingModule({
导入:[HttpClientTestingModule,NgbModule],
声明:[组件],
提供程序:[{提供:WindowObjectService,useClass:MockWindowObjectService}]
})
.compileComponents()。然后(()=>{
windowService=TestBed.get(WindowObjectService);
fixture=TestBed.createComponent(PhotoComponent);
组件=fixture.componentInstance;
});
}));
它('应该创建',()=>{
expect(component.toBeTruthy();
});
它('应该调用窗口对象服务',()=>{
windowSpy=spyOn(WindowsService,'browserWindow')。和.callThrough();
期望(WindowsService.browserWindow).toHaveBeenCalled();
});
});
我在这里要做的是模拟窗口对象服务并确定它已被调用。一旦我确认它被成功调用,我想写的下一个测试就是确认它返回模拟值。我尝试了很多不同的测试配置,这只是最新的一次迭代,但似乎没有任何效果。我只犯了一个错误,那就是间谍没被叫来。有没有办法解决这个问题,让模拟和间谍工作

更新,添加photos.component.ts。这使用ng引导轮转和分页来显示幻灯片,每次显示一个图像,可以使用轮转箭头或分页组件进行导航。照片集合id来自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;
  }
}
从'@angular/core'导入{Component,OnInit,ViewChild};
从“../services/photos.service”导入{photoservice};
从“../models/photo”导入{IPhoto};
从'@ng bootstrap/ng bootstrap'导入{NgbCarousel,NgbCarouselConfig,NgbPaginationConfig};
从“../services/windowobject.service”导入{WindowObjectService};
@组成部分({
选择器:“应用程序照片”,
templateUrl:'./photos.component.html',
样式URL:['./photos.component.scss'],
提供者:[NgbCarouselConfig,WindowObjectService]
})
导出类组件实现OnInit{
//对“photosCarousel”的引用
@ViewChild(“photocarousel”)photocarousel:NgbCarousel;
私人影印服务:任何;
private\u windowService:WindowObjectService;
错误消息:字符串;
照片:IPhoto[]=新阵列;
page=1;
集合大小:数量;
tripReportId:字符串;
构造函数(carouseConfig:NgbCarouselConfig,分页配置:NgbPaginationConfig,phototsService:photoservice,
WindowsService:WindowObjectService){
carouselConfig.showNavigationRows=true;
carouselConfig.showNavigationIndicators=false;
carouselConfig.interval=0;//显示下一张幻灯片之前的时间量(毫秒)。
carouselConfig.wrap=false;
paginationConfig.pageSize=1;
paginationConfig.maxSize=5;
paginationConfig.size='sm';
paginationConfig.boundaryLinks=false;
这._photoservice=phototsService;
这是.\u windowService=windowService;
}
恩戈尼尼特(){
log('this.\u windowService.browserWindow.location.href',this.\u windowService.browserWindow.location.href');
this.tripReportId=this._windowService.browserWindow.location.href.split('?')[1]。split('=')[1];
此.\u photosService.getPhotos(此.tripReportId)。订阅(
照片=>{
this.photos=照片;
this.collectionSize=photos.length;
},
error=>this.errorMessage=错误
);
this.collectionSize=this.photos.length;
}
pageChanged(pageNumber:number):无效{
this.photocarousel.select(pageNumber.toString());
}
公共滑道(滑道数据){
this.page=slideData.current;
}
}

好的,这是我把你的代码放到这里时发现的

  • 正如我所怀疑的,您需要调用
    fixture.detectChanges()
    ,以便执行ngOnInit()
  • 因为您在@Component decorator的providers数组中声明了
    WindowObjectService
    ,所以不能在默认providers数组中替换为mock。相反,您需要使用
    overrideComponent()
    ,如StackBlitz中所示
  • 组件将WindowsService设置为构造函数中的组件变量。正因为如此,它使这个v