typescript 在测试文件中注入运行时加载的环境数据

vxqlmq5t  于 2023-01-31  发布在  TypeScript
关注(0)|答案(2)|浏览(98)

因为我们删除了环境文件,并且在引导应用模块之前加载了配置数据,所以我们在注入的字段方面遇到了问题(在测试文件中未定义)
main.ts

fetch('./assets/config/config.json')
  .then(response => response.json())
  .then((config: AppConfig) => {
    platformBrowserDynamic([{
      provide: APP_CONFIG,
      useValue: config
    }]).bootstrapModule(AppModule)
    .catch(err => console.error(err));
  });

app.module.ts

...
export class AppModule { }
export const APP_CONFIG = new InjectionToken<AppConfig>('ENV_DATA');

我们使用注入到服务中的APP_CONFIG对象作为:

constructor(@Inject(APP_CONFIG) private config: AppConfig) {}

问题出在app. component. spec. ts中。如果我们在app中使用了一个ItemsService(与APP_CONFIG有依赖关系),测试将失败,并显示一条奇怪的错误消息:

Uncaught ReferenceError: Cannot access 'AppComponent' before initialization
ReferenceError: Cannot access 'AppComponent' before initialization

规格档桉

describe('AppComponent', () => {
  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [
        RouterTestingModule
      ],
      declarations: [
        AppComponent
      ],
    }).compileComponents();
  });

  it('should create the app', () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.componentInstance;
    expect(app).toBeTruthy();
  });
});

无论如何,如果我在configureTestingModule提供程序数组中插入{provide: APP_CONFIG, useValue: {}},错误仍然会发生。
尝试示例化组件并在***it***case中注入服务,但仍不起作用:

it('should check service injection', inject([ItemsService], (itemsService: ItemsService) => {
  let fix = TestBed.createComponent(AppComponent);
  let comp = fix.componentInstance;
  expect(comp).toBeTruthy();
}));

**另一个奇怪的行为:**如果我在ItemsService中注入字符串令牌,作为constructor(@Inject('ENV_DATA') private config: AppConfig) {}测试将工作(同时,要求在configureTestingModule中注入'ENV_DATA'!!!!但是,构建将失败,因为ENV_DATA(在main.ts中)没有注入应用程序。

有人经历过类似的事情吗?thx

e4eetjau

e4eetjau1#

如果AppComponent依赖于ItemsService,那么在单元测试中我将模拟ItemsService

// !! Declare mock
let mockItemsService: jasmine.SpyObj<ItemsService>;

beforeEach(async () => {
    // !! Create mock
    mockItemsService = jasmine.createSpyObJ<ItemsService>('ItemsService', {}, {});
    await TestBed.configureTestingModule({
      imports: [
        RouterTestingModule
      ],
      declarations: [
        AppComponent
      ],
      providers: [
        // !! Provide the mock for the real.
        { provide: ItemsService, useValue: mockItemsService }
      ]
    }).compileComponents();
  });

下面是如何根据服务模拟组件:https://testing-angular.com/testing-components-depending-on-services/#testing-components-depending-on-services

qrjkbowd

qrjkbowd2#

我发现一些工作的基础上,改变应用程序的目标从es2017es5,并添加行"emitDecoratorMetadata": false
但这看起来像是一种权衡,而不是解决方案

相关问题