如何从Angular 2测试中的服务模拟服务
我正在为一项服务编写测试。它调用另一个名为“SignlarService”的服务。所以我想模仿SingnalrService,我不知道如何模仿 我有以下错误:如何从Angular 2测试中的服务模拟服务,angular,karma-jasmine,Angular,Karma Jasmine,我正在为一项服务编写测试。它调用另一个名为“SignlarService”的服务。所以我想模仿SingnalrService,我不知道如何模仿 我有以下错误: TypeError: signalr.createHubConnetion is not a function 这是vendorService的.spec文件 import { TestBed, async, inject } from '@angular/core/testing'; import { DebugElement } f
TypeError: signalr.createHubConnetion is not a function
这是vendorService的.spec文件
import { TestBed, async, inject } from '@angular/core/testing';
import { DebugElement } from '@angular/core';
import { By } from '@angular/platform-browser';
import { Observable } from 'rxjs';
import { VendorService } from './game-vendor.service';
import { HttpModule, Http, BaseRequestOptions } from '@angular/http';
import { MockBackend } from '@angular/http/testing';
import { SignalrService } from '../shared/services/signalr.service';
import { Store } from '@ngrx/store';
import { RequestService } from '../shared/services/request-handler.service';
import { AppConfig } from './../app.config';
import { MockStore } from '../shared/helper/mock-store-helper';
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
{ provide: RequestService, useValue: {} },
{ provide: SignalrService, useValue: {} },
{ provide: Store, useClass: MockStore },
VendorService,
{
provide: Http,
userFactory: (mockBackend: MockBackend, options: BaseRequestOptions) => {
return new Http(mockBackend, options);
},
deps: [ MockBackend, BaseRequestOptions ],
},
MockBackend,
BaseRequestOptions,
AppConfig,
],
});
});
it('should toBeTruthy', inject([VendorService], (service: VendorService) => {
expect(service).toBeTruthy();
}));
});
这是vendorService.ts,它调用SignalrService
@Injectable()
export class VendorService {
VendorServiceUrl: string = `${this.config.baseUrl}v1/Vendors`;
signalrUrl: string = `${this.config.baseUrl}v1/Vendors/signalr`;
signalrHubName: string = 'VendorsHub';
constructor(
private request: RequestService,
private config: AppConfig,
private signalr: SignalrService,
private store: Store<any>,
) {
signalr.createHubConnetion(this.signalrUrl)
.createHubProxy(this.signalrHubName)
.event$
.map(e =>
new VendorActions.GetVendorAction())
.subscribe(store);
}
}
@Injectable()
导出类供应商服务{
VendorServiceUrl:string=`${this.config.baseUrl}v1/Vendors`;
signalrUrl:string=`${this.config.baseUrl}v1/Vendors/signalr`;
signalhubName:string='VendorsHub';
建造师(
私有请求:RequestService,
私有配置:AppConfig,
专用信号员:信号服务,
私家店,
) {
signalr.createHubConnetion(this.signalrUrl)
.createHubProxy(此.signalHubName)
.事件$
.map(e=>
新建VendorActions.GetVendorAction())
.订阅(商店);
}
}
这里是signalservice.ts
import { Injectable, Inject, NgZone } from '@angular/core';
import { Subject } from 'rxjs/Subject';
import { Observable } from 'rxjs/Observable';
export class SignalrWindow {
$: any;
}
export enum ConnectionState {
Idle = 0,
Connecting = 1,
Connected = 2,
Reconnecting = 3,
Disconnected = 4,
}
export class SignalrEvent {
name: string;
payload: any;
}
export class HubConnection {
constructor(
private zone: NgZone,
public connection: any,
public connectionState$: Observable<ConnectionState>,
public error$: Observable<string>) { }
createHubProxy(hubName: string): HubProxy {
const eventSubject = new Subject<SignalrEvent>();
if (this.connection) {
const newHub = this.connection.createHubProxy(hubName);
newHub.on('onEvent', (event: SignalrEvent) => {
this.zone.run(() => eventSubject.next(event));
});
}
return new HubProxy(eventSubject.asObservable());
}
}
export class HubProxy {
constructor(public event$: Observable<SignalrEvent>) { }
}
@Injectable()
export class SignalrService {
constructor(
@Inject(SignalrWindow) private window: SignalrWindow,
private zone: NgZone,
) { }
createHubConnetion(url: string): HubConnection {
const connectionStateSubject = new Subject<ConnectionState>();
const errorSubject = new Subject<any>();
if (this.window.$ === undefined || this.window.$.hubConnection === undefined) {
console.warn('SignalR failed to load. Some features have been disabled.');
return new HubConnection(this.zone, null, connectionStateSubject.asObservable(), errorSubject.asObservable());
}
const connection = this.window.$.hubConnection();
connection.url = url;
connection.stateChanged((state: any) => {
let newState: ConnectionState;
switch (state.newState) {
case this.window.$.signalR.connectionState.connecting:
newState = ConnectionState.Connecting;
break;
case this.window.$.signalR.connectionState.connected:
newState = ConnectionState.Connected;
break;
case this.window.$.signalR.connectionState.reconnecting:
newState = ConnectionState.Reconnecting;
break;
case this.window.$.signalR.connectionState.disconnected:
newState = ConnectionState.Disconnected;
break;
default:
newState = ConnectionState.Idle;
}
this.zone.run(() => connectionStateSubject.next(newState));
});
connection.error((error: any) => {
this.zone.run(() => errorSubject.next(error));
});
connection.start();
return new HubConnection(this.zone, connection, connectionStateSubject.asObservable(), errorSubject.asObservable());
}
}
从'@angular/core'导入{Injectable,injection,NgZone};
从'rxjs/Subject'导入{Subject};
从“rxjs/Observable”导入{Observable};
导出类信号窗口{
$:任何;
}
导出枚举连接状态{
怠速=0,
连接=1,
已连接=2,
重新连接=3,
断开连接=4,
}
出口级信号灯{
名称:字符串;
有效载荷:任何;
}
导出类连接{
建造师(
私人区域:NgZone,
公共关系:任何,
公共连接状态$:可见,
公共错误$:可观测的{}
createHubProxy(hubName:string):HubProxy{
const eventSubject=新主题();
如果(此连接){
const newHub=this.connection.createHubProxy(hubName);
newHub.on('onEvent',(事件:SignalrEvent)=>{
this.zone.run(()=>eventSubject.next(事件));
});
}
返回新的HubProxy(eventSubject.asObservable());
}
}
导出类代理{
构造函数(公共事件$:可观察){}
}
@可注射()
导出类信号服务{
建造师(
@注入(信号窗口)专用窗口:信号窗口,
私人区域:NgZone,
) { }
createHubConnetion(url:string):HubConnection{
const connectionstatepubject=新主题();
const errorSubject=新主题();
if(this.window.$==未定义| | this.window.$.hubConnection==未定义){
console.warn('信号器加载失败。某些功能已被禁用');
返回新的HubConnection(this.zone,null,connectionStateSubject.asObservable(),errorSubject.asObservable());
}
const connection=this.window.$.hubConnection();
connection.url=url;
connection.stateChanged((状态:any)=>{
let newState:ConnectionState;
开关(state.newState){
案例此.window.$.signalR.connectionState.connecting:
newState=ConnectionState.Connecting;
打破
案例此.window.$.signalR.connectionState.connected:
newState=ConnectionState.Connected;
打破
此案例。窗口。$.signalR.connectionState.Reconnection:
newState=连接状态。正在重新连接;
打破
案例此.window.$.signalR.connectionState.disconnected:
newState=ConnectionState.Disconnected;
打破
违约:
newState=ConnectionState.Idle;
}
this.zone.run(()=>connectionStateSubject.next(newState));
});
connection.error((错误:any)=>{
this.zone.run(()=>errorSubject.next(error));
});
connection.start();
返回新的HubConnection(this.zone,connection,connectionStateSubject.asObservable(),errorSubject.asObservable());
}
}
首先,没有所谓的userValue
。它是useValue
。您可能需要在useValue
对象上定义存根方法,比如createHubConnection:createSpy()。和.callFake(()=>new HubConnectionMock)
,通常就这么简单。