gpt4 book ai didi

模块构造函数中的 Angular 5 测试代码

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

我正在尝试测试模块构造函数之一中的代码。基本上,模块(名为 GraphqlModule)配置一个服务(名为 Graphql)并提供它。配置发生在模块的构造函数中。

这是我用来测试模块的代码。

it('should use the GraphqlConfigs and ServerConfigs', (done: DoneFn) => {

// Adding spies to Config classes
let serverConfigs = new ServerConfigs();
let serverDomainSpy = spyOnProperty(serverConfigs, 'ServerDomain', 'get').and.callThrough();
let serverPortSpy = spyOnProperty(serverConfigs, 'ServerPort', 'get').and.callThrough();

let gqlConfigs = new GraphqlConfigs();
let protocolSpy = spyOnProperty(gqlConfigs, 'EndpointProtocol', 'get').and.callThrough();
let endpointNameSpy = spyOnProperty(gqlConfigs, 'EndpointName', 'get').and.callThrough();

TestBed.configureTestingModule({
imports: [ GraphqlModule ],
providers: [
{provide: ServerConfigs, useValue: serverConfigs}, // Replacing real config classes with the ones spied on.
{provide: GraphqlConfigs, useValue: gqlConfigs}
]

}).compileComponents().then(() => {

// This line seems to make Angular instantiate GraphqlModule
const graphql = TestBed.get(Graphql) as Graphql;

expect(serverDomainSpy.calls.count()).toBe(1, 'ServerConfigs.ServerDomain was not used.');
expect(serverPortSpy.calls.count()).toBe(1, 'ServerConfigs.ServerPort was not used.');

expect(protocolSpy.calls.count()).toBe(1, 'GraphqlConfigs.EndpointProtocol was not used.');
expect(endpointNameSpy.calls.count()).toBe(1, 'GraphqlConfigs.EndpointName was not used.');

done();
});
});

按原样,测试通过并有效,但如果我不使用以下(无用的)行 const graphql = TestBed.get(Graphql) as Graphql; GraphqlModule 在测试执行后被实例化,这使得测试失败。

因为它是 GraphqlModule 提供 Graphql 服务,我知道 Angular 中有一些延迟加载算法,当我执行 TestBed.get(Graphql) 时会触发。没关系...我的问题是,有没有办法让我的模块以更明确的方式加载?

这是 GraphqlModule 类定义:

imports...

@NgModule({
imports: [
CommonModule,
HttpClientModule,
ApolloModule,
HttpLinkModule
],
declarations: [],

providers: [
Graphql, // Is an alias for Apollo
GraphqlConfigs
]
})
export class GraphqlModule {

constructor(
@Optional() @SkipSelf() parentModule: GraphqlModule,
graphql: Graphql,
httpLink: HttpLink,
serverConfigs: ServerConfigs,
graphqlConfigs: GraphqlConfigs
) {

// Making sure this is not imported twice.
// https://angular.io/guide/ngmodule#prevent-reimport-of-the-coremodule
if (parentModule) {
throw new Error(
'GraphqlModule is already loaded. Import it in the '+CoreModule.name+' only.');
}

// Gql setup:


const gqlHttpLink = httpLink.create({
uri: GraphqlModule.buildEndpointUrl(serverConfigs, graphqlConfigs)
});

graphql.create({
link: gqlHttpLink,
cache: new InMemoryCache(),
});
}

private static buildEndpointUrl(serverConfigs: ServerConfigs, graphqlConfigs: GraphqlConfigs): string {

return graphqlConfigs.EndpointProtocol + // eg. http://
serverConfigs.ServerDomain+":"+serverConfigs.ServerPort+'/' + // eg. example.com:80/
graphqlConfigs.EndpointName; // eg. graphql
}
}

最佳答案

Graphql 已经在根注入(inject)器的 GraphqlModule 构造函数中实例化,并且 GraphqlModule 在 TestBed imports< 中指定时立即实例化。不涉及延迟加载。

this answer 中所述,TestBed 注入(inject)器在第一次 inject 回调调用,或 TestBed.get,或 TestBed.createComponent 调用时实例化。注入(inject)器在第一次注入(inject)之前不存在,因此不存在任何模块或提供程序实例。由于几乎所有 TestBed 测试都至少在 itbeforeEach 中执行这些调用之一,因此通常不会出现此问题。

由于此测试不需要 graphql 实例,因此为了让测试通过,它可以只是:

TestBed.get(Injector);

或者:

TestBed.get(TestBed);

此外,.compileComponents().then(() => { ... })done() 是不必要的,测试不涉及组件并且是同步的。

注入(inject)器需要手动实例化的事实表明此测试不需要 TestBed,尽管它是有益的,因为这样可以测试 GraphqlModule 构造函数 DI 注释,包括用于 parentModule.

关于模块构造函数中的 Angular 5 测试代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47706524/

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