我正在尝试测试一个处理SignalR连接的Angular服务,它将SignalR的代码作为InjectionToken。
下面是提供程序文件:
// signalr-provider.ts
import { InjectionToken } from '@angular/core';
export const SIGNALR_TOKEN = new InjectionToken('signalR');
export function signalRFactory() {
return window['signalR'];
}
export const SIGNALR_PROVIDER = [ { provide: SIGNALR_TOKEN, useFactory: signalRFactory } ];这就是服务:
// signalr-service.ts
import { Injectable, Inject } from '@angular/core';
import { SIGNALR_TOKEN } from './signalr-provider';
import { HubConnection } from '@aspnet/signalr';
import { environment } from '../../../environments/environment';
@Injectable()
export class SignalrService {
private hubConnection: HubConnection;
private baseUrl: string = environment.baseUrl;
constructor(@Inject(SIGNALR_TOKEN) private signalR: any) {
this.init();
}
init(): void {
this.hubConnection = new this.signalR.HubConnectionBuilder().withUrl(`${this.baseUrl}/hubs/test`).build();
}
}令牌在app模块中提供,如下所示:
// From app.module.ts
@NgModule({
declarations: [...],
imports: [...],
providers: [ SIGNALR_PROVIDER, SignalrService ],
bootstrap: [ AppComponent]
})
export class AppModule {}到目前为止,我还没有在我的测试文件中模拟InjectionToken,每次都会得到一条NullInjectorError: No provider for InjectionToken signalR!消息。
这是我的第一次尝试,从signalRFactory函数返回一个模拟对象,其中只包含初始连接所需的属性:
// signalr-service.spec.ts
import { TestBed, async } from '@angular/core/testing';
import { InjectionToken } from '@angular/core';
import { SignalrService } from './signalr-service';
const SIGNALR_TOKEN = new InjectionToken('signalR');
function signalRFactory() {
return {
HubConnectionBuilder: () => {
return {
withUrl: (url) => {
return {
build: () => {}
};
}
};
}
};
}
const SIGNALR_PROVIDER = [ { provide: SIGNALR_TOKEN, useFactory: signalRFactory } ];
describe('ConnectionService', () => {
beforeEach(
async(() => {
TestBed.configureTestingModule({
providers: [ SIGNALR_PROVIDER, SignalrService ]
});
})
);
it('should exist', () => {
const connectionService = TestBed.get(SignalrService);
expect(connectionService).toBeTruthy();
});
});在我的第二次尝试中,我将模拟对象赋给了一个变量:
import { TestBed, async } from '@angular/core/testing';
import { InjectionToken } from '@angular/core';
import { SignalrService } from './signalr-service';
const SIGNALR_TOKEN = new InjectionToken('signalR');
const SIGNALR_VALUE = {
HubConnectionBuilder: () => {
return {
withUrl: (url) => {
return {
build: () => {}
};
}
};
}
};
const SIGNALR_PROVIDER = [ { provide: SIGNALR_TOKEN, useValue: SIGNALR_VALUE } ];
describe('ConnectionService', () => {
beforeEach(
async(() => {
TestBed.configureTestingModule({
providers: [ SIGNALR_PROVIDER, SignalrService ]
});
})
);
it('should exist', () => {
const connectionService = TestBed.get(SignalrService);
expect(connectionService).toBeTruthy();
});
});在我的第三次尝试中,我取出了SIGNALR_PROVIDER,并尝试按工厂和直接值在提供程序数组中直接提供值:
直接值:
import { TestBed, async } from '@angular/core/testing';
import { InjectionToken } from '@angular/core';
import { SignalrService } from './signalr-service';
const SIGNALR_TOKEN = new InjectionToken('signalR');
const SIGNALR_VALUE = {
HubConnectionBuilder: () => {
return {
withUrl: (url) => {
return {
build: () => {}
};
}
};
}
};
describe('ConnectionService', () => {
beforeEach(
async(() => {
TestBed.configureTestingModule({
providers: [ { provide: SIGNALR_TOKEN, useValue: SIGNALR_VALUE }, SignalrService ]
});
})
);
it('should exist', () => {
const connectionService = TestBed.get(SignalrService);
expect(connectionService).toBeTruthy();
});
});工厂:
import { TestBed, async } from '@angular/core/testing';
import { InjectionToken } from '@angular/core';
import { SignalrService } from './signalr-service';
const SIGNALR_TOKEN = new InjectionToken('signalR');
function signalRFactory() {
return {
HubConnectionBuilder: () => {
return {
withUrl: (url) => {
return {
build: () => {}
};
}
};
}
};
}
describe('ConnectionService', () => {
beforeEach(
async(() => {
TestBed.configureTestingModule({
providers: [ { provide: SIGNALR_TOKEN, useFactory: signalRFactory }, SignalrService ]
});
})
);
it('should exist', () => {
const connectionService = TestBed.get(SignalrService);
expect(connectionService).toBeTruthy();
});
});每一次尝试都会给我NullInjectorError: No provider for InjectionToken signalR!我卡住了。很明显,关于InjectionToken有一些我不知道的事情。有谁能给我指个方向吗?
发布于 2018-10-10 21:13:13
解决了这个问题--我的问题是我在测试文件中重新定义了令牌,所以我的测试为我的模拟对象提供了一个与我的服务期望的令牌完全不同的令牌。将其更改为以下内容即可解决此问题:
// signalr-service.spec.ts
import { TestBed, async } from '@angular/core/testing';
import { InjectionToken } from '@angular/core';
import { SignalrService } from './signalr-service';
import { SIGNALR_TOKEN } from './signalr-provider'; // This is the change
function signalRFactory() {
return {
HubConnectionBuilder: () => {
return {
withUrl: (url) => {
return {
build: () => {}
};
}
};
}
};
}
const SIGNALR_PROVIDER = [ { provide: SIGNALR_TOKEN, useFactory: signalRFactory } ];
describe('ConnectionService', () => {
beforeEach(
async(() => {
TestBed.configureTestingModule({
providers: [ SIGNALR_PROVIDER, SignalrService ]
});
})
);
it('should exist', () => {
const connectionService = TestBed.get(SignalrService);
expect(connectionService).toBeTruthy();
});
});https://stackoverflow.com/questions/52607342
复制相似问题