gpt4 book ai didi

Angular 测试 - 模拟 InjectionToken

转载 作者:行者123 更新时间:2023-12-03 17:04:59 24 4
gpt4 key购买 nike

我正在尝试测试处理 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();
}
}

token 在 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 并尝试通过工厂和直接值直接在 providers 数组中提供值:

直接值(value):
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,我显然有一些不知道的地方。谁能指出我正确的方向?

最佳答案

想通了——我的问题是我在测试文件中重新定义了 token ,所以我的测试为我的模拟对象提供了一个与我的服务所期望的完全不同的 token 。将其更改为此修复了它:

// 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();
});
});

关于Angular 测试 - 模拟 InjectionToken,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52607342/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com