[英]Angular tests failing after using APP_INITIALIZER to load config file
我是 Angular 的新手,所以请原谅这个简单的问题。 我写了一个应用程序,它使用 HttpClient 和 APP_INITIALIZER 加载配置 json,但现在我的所有测试都失败并显示消息:类型错误:无法读取未定义的属性(读取“主题”)。 你能给我指出正确的方向吗?
app.component.spec.ts:
import { TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';
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();
});
});
app-config.service.ts:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { firstValueFrom } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class AppConfigService {
static config: IAppConfig;
constructor(private http: HttpClient) {}
loadConfig() {
return new Promise<void>(async (resolve, reject) => {
try {
const get$ = this.http.get('assets/app.config.json');
const configFile = await firstValueFrom(get$);
AppConfigService.config = <IAppConfig>configFile;
resolve();
} catch (e) {
console.error('Error loading config file', e);
reject(e);
}
});
}
}
export interface IAppConfig {
theme: string;
}
应用程序模块.ts
import { HttpClientModule } from '@angular/common/http';
import { NgModule, APP_INITIALIZER } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppConfigService } from './app-config.service';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
// Function to load application config on application startup
export function initializeApp(appConfigService: AppConfigService) {
return (): Promise<any> => {
return appConfigService.loadConfig();
};
}
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, AppRoutingModule, HttpClientModule],
providers: [
AppConfigService,
{
provide: APP_INITIALIZER,
useFactory: initializeApp,
deps: [AppConfigService],
multi: true,
},
],
bootstrap: [AppComponent],
})
export class AppModule {}
应用程序组件.ts
import { Component } from '@angular/core';
import { AppConfigService } from './app-config.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
})
export class AppComponent {
theme = AppConfigService.config.theme;
}
你有几个问题,首先你不应该使用class
来设置属性。 该服务应声明一些属性,并且在此服务中,您可以设置this.config = someValue
。
然后,如果你想在一个组件中使用服务,你必须注入它,基本上是通过依赖注入的构造函数: https://angular.io/guide/dependency-injection
constructor(heroService: HeroService)
然后您将添加服务 - 最好使用 mocking - 作为测试文件中的提供者。 您可以像这样使用来自 Jasmine 的Spy
实现这一点:
https://codecraft.tv/courses/angular/unit-testing/mocks-and-spies/
另外,我会放弃更强大的 Observables Promises。 干杯!
所以我做了一些改变,这就是我带来的。 它正在工作,所有测试也都正常。 也不需要 APP_INITIALIZE。 你现在看到任何问题了吗?
app.component.spec.ts:
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [RouterTestingModule, HttpClientTestingModule],
declarations: [AppComponent],
}).compileComponents();
});
it('should create the app', () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app).toBeTruthy();
});
});
app-config.service.ts:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Injectable({
providedIn: 'root',
})
export class AppConfigService {
constructor(private http: HttpClient) {}
loadConfig() {
return this.http.get<IAppConfig>('assets/app.config.json');
}
}
export interface IAppConfig {
theme: string;
}
应用程序模块.ts:
import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, AppRoutingModule, HttpClientModule],
bootstrap: [AppComponent],
})
export class AppModule {}
应用程序组件.ts:
import { Component } from '@angular/core';
import { AppConfigService, IAppConfig } from './app-config.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
})
export class AppComponent {
config: IAppConfig = {
theme: 'blue'
};
constructor(appConfigService: AppConfigService) {
appConfigService.loadConfig().subscribe(data => this.config = data)
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.