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

模块构造函数中的Angular 5测试代码,angular,testing,jasmine,Angular,Testing,Jasmine,我试图测试模块构造函数中的代码。基本上,模块(名为GraphqlModule)配置并提供服务(名为Graphql)。配置发生在模块的构造函数中 下面是我用来测试模块的代码 it('should use the GraphqlConfigs and ServerConfigs', (done: DoneFn) => { // Adding spies to Config classes let serverConfigs = new ServerConfigs();

我试图测试模块构造函数中的代码。基本上,模块(名为
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)作为graphql执行测试后,将实例化
GraphqlModule
,这会导致测试失败

由于是
GraphqlModule
提供了
Graphql
服务,因此我知道在我执行
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
已经在根注入器的
GraphqlModule
构造函数中实例化,当在TestBed
imports
中指定时,
GraphqlModule
急切地实例化。不涉及延迟加载

如中所述,在第一次
inject
回调调用或
TestBed.get
TestBed.createComponent
调用中实例化了测试床注入器。注入器在第一次注入之前不存在,因此不存在任何模块或提供程序实例。由于几乎所有的测试台测试都至少在
it
之前执行其中一个调用,所以这个问题通常不会出现

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

TestBed.get(Injector);
或:

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


注入器需要手动实例化的事实表明此测试不需要TestBed,尽管它是有益的,因为这样可以测试
GraphqlModule
constructor DI注释,包括
parentModule

的注释,不清楚您在测试什么,因为问题不包含GraphqlModule或Graphql。我正在尝试测试模块构造函数中的代码-它没有列出。@estus该模块在
测试床的导入配置中列出。这个测试是测试
GraphqlModule
不同功能的测试套件的一部分。对不起,我把它放在了问题的主体中,但是,我不确定它是否与我的问题相关。有必要了解发生了什么,谢谢。哇,史诗般的答案。谢谢
TestBed.get(TestBed);