angular - Angular Unit Testing - 使用 TestBed 模拟注入服务的异步调用
问题描述
我需要为以下内容编写单元测试DataService
,
@Injectable()
export class DataService {
constructor(private config: ConfigService, private http: HttpClient) {
}
.....
someMethod(){
let apiUrl = this.config.get('api').url; // LINE 1
}
}
ConfigService
被注入的有DataService
一个load
从 json 文件获取配置的函数。该load
函数将在应用程序初始化时调用。
export function configServiceFactory(config: ConfigService) {
return () => config.load();
}
...
providers: [
ConfigService,
{
provide: APP_INITIALIZER,
useFactory: configServiceFactory,
deps: [ConfigService],
multi: true
}
]
这是data-service.spect.ts
文件的一部分,
...
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
HttpClientTestingModule
],
providers: [DataService, ConfigService]
});
mock = TestBed.get(HttpTestingController);
service = TestBed.get(DataService);
});
....
所以当我运行测试时,LINE 1
我知道这this.config.get('api')
是未定义的。我可以理解这是因为ConfigService
没有从 JSON 加载数据。那么现在我怎样才能让注入的服务在单元测试期间也进行异步调用呢?
解决方案
在编写单元测试时,您可能希望模拟您拥有的每个依赖项。您已经HttpClient
通过导入做到HttpClientTestingModule
了这一点,因此您需要对ConfigService
.
有两种方法可以做到这一点。
1-假服务(存根)
export class ConfigServiceStub {
get(input: string) {
// return static value instead of calling an API
}
}
...
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
HttpClientTestingModule
],
providers: [DataService,
{provide: ConfigService, useClass: ConfigServiceStub}
]
});
mock = TestBed.get(HttpTestingController);
service = TestBed.get(DataService);
});
通过这种方式,您DataService
不会调用 real ConfigService
,而是调用 的get
方法ConfigServiceStub
。使用Stub
s 时,无需担心其他依赖ConfigService
有。您只需实现要覆盖的方法。
2-间谍
您可以在不想调用的方法上创建间谍。
it('run some test', inject([DataService], (service: DataService) => {
spyOn(service.config, 'get').and.returnValue('someString');
// run your tests here
});
即使ConfigService.get
在上面的示例中方法不会被调用,Angular 仍然需要创建一个实例,ConfigService
在某些示例中可能很难这样做,或者可能导致创建太多其他服务以进行简单测试。
我会选择选项1
有关间谍的更多信息,请查看此处
推荐阅读
- python-3.x - 如何从 xxx.log 文件中读取所有 IP 地址并打印它们的计数?
- oozie - OOZIE 卡在 RUNING 状态
- javascript - 当我发送 res.send(body)
- ios - 带有开始和结束时间的每日本地通知
- typescript2.0 - 如何读取对象的属性值
- android - Keras LSTM 模型到 android
- node.js - 打字稿导入全局节点模块失败
- angular - 在 Visual Studio Code 中使用 npm 不会获得 fontawesome css 文件
- c++ - 为什么默认情况下不是字符串文字 constexpr ?
- node.js - 在 Angular 中,使用 Renderer 比 ElementRef 有什么优势?