angular - 如何使用 Injector 在函数中模拟注入的服务
问题描述
在 Angular 7.x 中,我有一个全局错误处理,用 Injector 注入他的服务。所以每个函数都有一个对注入器的引用,如下所示:
import { ErrorHandler, Injectable, Injector, NgZone } from '@angular/core';
import { Router } from '@angular/router';
import { LoggingService } from '../logging/logging.service';
import { EnvironmentService } from '../services/environment.service';
@Injectable()
export class GlobalErrorHandler implements ErrorHandler {
constructor(private readonly injector: Injector, private readonly zone: NgZone) {}
handleError(error: any): void {
// Handle Client Error (Angular Error, ReferenceError...)
this.processError(error);
throw error;
}
processError(error: any): void {
const environmentService = this.injector.get(EnvironmentService);
const environment = environmentService.getEnvironment();
if (!environment.production) {
console.error(error);
} else {
// Log the expection to the logger
this.logException(error);
this.zone.run(() => {
this.navigateToErrorPage(error);
});
}
}
private logException(error: any): void {
const loggingService = this.injector.get(LoggingService);
loggingService.logException(error);
}
private navigateToErrorPage(error: any): void {
const router = this.injector.get(Router);
router.navigate(['/500'], { queryParams: { error } });
}
}
如您所见,在processError
函数中我注入了环境服务。该服务的唯一目标是能够在我的规范测试中模拟环境。我在另一个服务测试中这样做,但我使用依赖注入而不是this.injector.get(...)
函数。
有谁知道我怎么嘲笑这个?
it('should log the error if the environment is in production', () => {
// Arrange
const environmentSpy = jasmine.createSpyObj('EnvironmentService', 'getEnvironment'); ??? How do I mock this ???
const error: Error = new Error('New Error');
spyOn<any>(errorHandler, 'logException');
// Act
errorHandler.processError(error);
// Assert
expect(errorHandler['logException']).toHaveBeenCalledWith(error);
});
解决方案
您可以监视 Injector 并返回一个假类来代替具有自定义getEnvironment()
方法的 EnvironmentService:
spyOn(TestBed.get(Injector), 'get').and.callFake((token) => {
if (token === EnvironmentService) {
// Return a mocked EnvironmentService class
return {
getEnvironment: () => { return { production: true }; }
};
} else {
// Otherwise, return whatever was originally defined in the TestBed
return TestBed.get(token);
}
});
或者,您可以在 EnvironmentService 上使用真正的 Injector 和 spy:
spyOn(TestBed.get(EnvironmentService), 'getEnvironment').and
.returnValue({ production: true });
推荐阅读
- npm - 错误代码:135 - 在 package.json 中调用 npm run protractor 时 ECONNREFUSED
- reactjs - ASP.NET Core 3.1 为反应应用程序提供静态文件:找到 index.html 和图标,但没有找到 js 文件
- ios - 使用 ReplayKit 广播时将 CMSampleBuffer 转换为 .mov
- here-api - “这些凭据不授权访问”(403)
- pyspark - Pyspark,如何使用udf计算泊松分布?
- php - Google 访问令牌不会在离线访问时自动刷新
- python - docker:来自守护进程的错误响应:OCI 运行时创建失败:没有这样的文件或目录”:未知
- build - Fortran 新手:如何在 Geany 中编译/构建多个 Fortran 文件
- python - 无法在 django 中编写动态元标记
- java - Apache POI - 饼图 - java.lang.IllegalStateException:类别和值必须具有相同的点数