错误:尝试在设置之前获取AngularJS注入器

时间:2019-01-15 06:21:03

标签: javascript angular jasmine karma-jasmine

我正在测试一个在内部使用angular js组件的angular 7组件。 我正在使用茉莉花和业力进行测试。 我正在

角度混合-在运行**Error: Trying to get the AngularJS injector before it being set.**时为ng test my-app-name

app-module-ts-

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, APP_INITIALIZER } from '@angular/core';
import { UpgradeModule, downgradeComponent } from '@angular/upgrade/static';

import { AppComponent } from './app.component';
import { BusyOverlayModule } from '../../../app-shared/src/lib/busy-overlay/busy-overlay.module';
import { L10nTranslationModule } from '../../../app-shared/src/lib/l10n-translation/l10n-translation.module';
import { LocalizationService } from '../../../app-shared/src/lib/l10n-translation/localization.service';
import { WatchlistModule } from './watchlist/watchlist.module';

import oprRtsmViewPickerModuleName
  from '../../../../../../shared/shared-html/js/directives/oprRtsmViewPicker/oprRtsmViewPicker.module.js';
import oprTableFooterModuleName
  from '../../../../../../shared/shared-html/js/directives/oprTableFooter/oprTableFooter.module.js';
import oprContextPanelModuleName
  from '../../../../../../shared/shared-html/js/directives/oprContextPanel/oprContextPanel/oprContextPanel.module.js';
import { FilterFactory } from 'angular';

import oprPopupServiceModuleName from '../../../../../../shared/shared-html/js/services/oprPopup.service';
import ciContextDataServiceModuleName from '../../../../../../shared/shared-html/js/services/ciContextData.service';

import watchlistOptionsLauncherComponent from './watchlist/options-menu/watchlistOptionsLauncherNg1';

import oprLocalizationUtil from '../../../../../../shared/shared-html/js/utils/oprLocalizationUtil';
import appConstantsUtil from '../../../../../../shared/shared-html/js/utils/appConstantsUtil';


import { setAngularJSGlobal } from '@angular/upgrade/static';
import { oprContextPanelApiServiceProvider } from '../../../ng1-adapters/adapters/opr-conext-panel-api-provider';
import { ciContextDataServiceProvider } from '../../../ng1-adapters/adapters/opr-conext-data-api-provider';
import { Oprl10nPipe } from '../../../app-shared/src/lib/l10n-translation/oprl10n.pipe';

declare const angular: angular.IAngularStatic;

setAngularJSGlobal(angular);

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    UpgradeModule,
    BusyOverlayModule,
    L10nTranslationModule,
    WatchlistModule
  ],
  providers: [
    {
      provide: APP_INITIALIZER,
      useFactory: onAppInit,
      multi: true
    },
    oprContextPanelApiServiceProvider,
    ciContextDataServiceProvider,
    Oprl10nPipe
  ],
  entryComponents: [
    AppComponent
  ]
})
export class AppModule {
  constructor(private upgrade: UpgradeModule, private localizationService: LocalizationService) { }

  /**
   * bootstrap hybrid AngularJS/Angular application with downgraded root Angular component
   */
  ngDoBootstrap() {

    const ng1L10nfilterFactory: angular.Injectable<FilterFactory> = function () {
      return (key) => {
        return oprLocalizationUtil.getLocalizedString(key);
      };
    };

    const ng1RootModule = angular.module('ng1-root', [
      oprPopupServiceModuleName,
      oprRtsmViewPickerModuleName,
      oprTableFooterModuleName,
      oprContextPanelModuleName,
      ciContextDataServiceModuleName
    ]).directive('oprRoot', downgradeComponent({component: AppComponent})).filter('oprL10n', ng1L10nfilterFactory)
      .component('oprOptionsMenuLauncher', watchlistOptionsLauncherComponent);
    this.localizationService.setOprLocalizeUtilObj(oprLocalizationUtil);
    this.upgrade.bootstrap(document.body, [ng1RootModule.name], {strictDi: false});

  }

}

export function onAppInit(): () => Promise<any> {
  return (): Promise<any> => {
    return new Promise((resolve, reject) => {
      const appConstants = appConstantsUtil.appConstants;
      /**
       * For Testing, Replace this  appConstants.locale.toLowerCase() code with en
       */
      oprLocalizationUtil.init(appConstants.locale.toLowerCase(), appConstants.staticContext, [
        'opr-watchlist',
        'opr-common'
      ], function () {
        resolve(true);
      });
    });
  };
}

app.component.ts-

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'opr-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {

  showBusyOverlay:boolean = true;

  ngOnInit() {
    this.showBusyOverlay = false;
  }
}

app.component.spec.ts-

import { TestBed, ComponentFixture, async } from '@angular/core/testing';
import * as angular from '@angular/upgrade/src/common/angular1';
import { UpgradeModule, setAngularJSGlobal } from '@angular/upgrade/static';
import { AppComponent } from './app.component';
import { AppSharedModule } from "../../../app-shared/src/lib/app-shared.module";
import { WatchlistComponent } from './watchlist/watchlist.component';
import { WatchlistFooterComponent } from './watchlist/watchlist-footer/watchlist-footer.component';
import { WatchlistHeaderComponent } from './watchlist/watchlist-header/watchlist-header.component';
import { WatchlistCardsComponent } from './watchlist/watchlist-cards/watchlist-cards.component';
import { WatchlistCardComponent } from "./watchlist/watchlist-cards/watchlist-card/watchlist-card.component";
import { WatchlistCardsModule } from './watchlist/watchlist-cards/watchlist-cards.module';
import { WatchlistModule } from './watchlist/watchlist.module';
import { ContextPanelApi } from 'shared/directives/oprContextPanel/oprContextPanel/oprContextPanelApi.service';
import { CiContextDataService } from '../../../../../../shared/shared-html/js/services/ciContextData.service';
import { CiContextMenuService } from '../../../app-shared/src/lib/ci-context-menu.service';

import { HttpClientModule, HttpClientXsrfModule } from '@angular/common/http';
import { Ng1AdaptersModule } from '../../../ng1-adapters/ng1-adapters.module';
import { FormsModule } from '@angular/forms';
import { BusyOverlayModule } from '../../../app-shared/src/lib/busy-overlay/busy-overlay.module';
import { L10nTranslationModule } from '../../../app-shared/src/lib/l10n-translation/l10n-translation.module';

import '../../../../../../shared/shared-html/test/config/index-mock.js';
import { Oprl10nPipe } from "../../../app-shared/src/lib/l10n-translation/oprl10n.pipe";
import { of } from 'rxjs';

export class MockBusyOverlayModule {

}

export class MockContextPanelApi {

}
export class MockCiContextDataService {

}
export class MockCiContextMenuService {

}

export class Oprl10nPipeStub {
    public get(key: any): any {
        return of(key);
    }

    public transform(key: any): any {
        return of(key);
    }
}

setAngularJSGlobal(angular);

describe('AppComponent', () => {
    window['getAppConstants'] = function () {
        return JSON.stringify({
            topazWebContext: "",
            mashupParams: { uim_sourceId: "0" },
            staticContext: "/base",
            locale: "en-us",
            oprWebContext: ""
        });
    };

    let component: AppComponent;
    let fixture: ComponentFixture<AppComponent>;

    beforeEach(async(() => {
        TestBed.configureTestingModule({
            imports: [
                UpgradeModule,
                BusyOverlayModule,
                HttpClientModule,
                AppSharedModule,
                // appConstantsUtil,
                // WatchlistModule,
                Ng1AdaptersModule,
                L10nTranslationModule,
                // WatchlistModule
                // WatchlistCardsModule
            ],
            providers: [
                { provide: Oprl10nPipe, useClass: Oprl10nPipeStub },
                // { provide: BusyOverlayModule, useClass: MockBusyOverlayModule }
                { provide: ContextPanelApi, useClass: MockContextPanelApi },
                { provide: CiContextDataService, useClass: MockCiContextDataService },
                { provide: CiContextMenuService, useClass: MockCiContextMenuService },
                // { provide: appConstantsUtil }
            ],
            declarations: [
                AppComponent,
                WatchlistComponent,
                WatchlistFooterComponent,
                WatchlistHeaderComponent,
                WatchlistCardComponent,
                WatchlistCardsComponent
            ]
            // imports: [
            //   WatchlistModule
            // ]
        }).compileComponents();
    }));

    beforeEach(() => {
        window['getAppConstants'] = function () {
            return JSON.stringify({
                topazWebContext: "",
                mashupParams: { uim_sourceId: "0" },
                staticContext: "/base",
                locale: "en-us",
                oprWebContext: ""
            });
        };
        fixture = TestBed.createComponent(AppComponent);
        component = fixture.componentInstance;
        fixture.detectChanges();
    });

    it('should create the app', () => {
        expect(component).toBeTruthy();
    });
});

我的angular js版本是1.6和Angular 7,正如我所说,我正在测试使用angular js组件的angular 7组件。 我在网上找到了一些链接-

Angular Hybrid Error: Trying to get the AngularJS injector before it being set

https://github.com/angular/angular/issues/23141

但没有帮助。我也无法在有角度的文档中找到任何内容。 请指导。

1 个答案:

答案 0 :(得分:1)

我通过添加

解决了这个问题
const upgrade = TestBed.get(UpgradeModule) as UpgradeModule;
upgrade.bootstrap(document);
const serviceWhichReliesonInjector = 

使用我的beforeEach方法。

之后,我只需通过

即可访问该服务
TestBed.get(ServiceWhichReliesonInjector)