gpt4 book ai didi

Angular Testing : TestBed doesn't require providing ApplicationRef

转载 作者:行者123 更新时间:2023-11-28 20:19:44 24 4
gpt4 key购买 nike

我正在遵循官方“测试”指南:https://angular.io/guide/testing为应用程序编写测试。

当我测试具有依赖项的服务时,我需要为这些依赖项提供模拟,但有趣的是,这对于 ApplicationRef 来说似乎并非如此,我真的很想知道为什么。

服务是这样的:

export class MyService {

constructor(
private dependentService: DependentService,
private applicationRef:ApplicationRef
){}
...

以及相应的测试规范:

describe('MyService', () => {
let dependentServiceSpy: jasmine.SpyObj<HttpClient>;

beforeEach(() => {
const dependentServiceSpy = jasmine.createSpyObj('DependentService', ['test']);

TestBed.configureTestingModule({
// Provide both the service-to-test and its (spy) dependency
// why is 'ApplicationRef' not needed here??
providers: [
MyService,
{ provide: DependentService, useValue: dependentService_spy }
]
});
});
...

});

由于“DependentService”和“ApplicationRef”都被注入(inject)到 MyService 构造函数中,因此我希望 TestBed 的提供程序数组中需要两者。但是,虽然省略“DependentService”会在测试中产生错误,但缺少“ApplicationRef”则不会

对此有合理的解释吗?

最佳答案

每个使用 TestBed 的 Angular 测试配置都以以下初始化开始:

getTestBed().initTestEnvironment(
BrowserDynamicTestingModule,
platformBrowserDynamicTesting()
);

Angular 测试环境将使用 BrowserDynamicTestingModule 来构造注入(inject)器,因为它适用于普通 Angular 模块(另请参阅 https://blog.angularindepth.com/angular-dependency-injection-and-tree-shakeable-tokens-4588a8f70d5d )。

Angular 合并 BrowserDynamicTestingModule 包含的提供程序。该模块声明如下:

@NgModule({
exports: [BrowserTestingModule],
providers: [
{provide: TestComponentRenderer, useClass: DOMTestComponentRenderer},
]
})
export class BrowserDynamicTestingModule {
}

其中 BrowserTestingModule 看起来像:

                /\
||

@NgModule({
exports: [BrowserModule],
providers: [
{provide: APP_ID, useValue: 'a'},
ELEMENT_PROBE_PROVIDERS,
{provide: NgZone, useFactory: createNgZone},
]
})
export class BrowserTestingModule {
}

BrowserModule是:

                /\
||

@NgModule({providers: BROWSER_MODULE_PROVIDERS, exports: [CommonModule, ApplicationModule]})
export class BrowserModule {
...
}

最后 ApplicationModule 声明 ApplicationRef:

                 /\
||

export const APPLICATION_MODULE_PROVIDERS: StaticProvider[] = [
{
provide: ApplicationRef,
useClass: ApplicationRef,
deps:
[NgZone, Console, Injector, ErrorHandler, ComponentFactoryResolver, ApplicationInitStatus]
},
...
];


@NgModule({providers: APPLICATION_MODULE_PROVIDERS})
export class ApplicationModule {
// Inject ApplicationRef to make it eager...
constructor(appRef: ApplicationRef) {}
}

正如您所看到的,ApplicationRef 提供程序也被急切地实例化。

这样就没有魔法了,Angular 只是使用相同的算法,就好像它会解析用户定义的 NgModule 中的提供程序

关于 Angular Testing : TestBed doesn't require providing ApplicationRef,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51178622/

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