【发布时间】:2020-07-31 08:51:37
【问题描述】:
我有一个服务,它需要依赖另一个服务,而另一个服务又需要依赖两个抽象类。
(ThemeConfigService -> (SettingsService -> SettingsLoader, NavigationLoader))
我已经让测试失败了,因为它找不到通过抽象类公开的方法(不是函数异常)。
我不知道我是怎么通过这个的,网上的各种搜索都证明不是很有帮助。
这是我试图充实测试“theme-config.service.ts”的主题配置服务
@Injectable({
providedIn: 'root'
})
export class ThemeConfigService {
constructor(
private platform: Platform,
private router: Router,
private settings: SettingsService
) {
// code removed for brevity
}
}
这里是正在测试的服务“settings.service.ts”
@Injectable()
export class SettingsService {
constructor(public settingsLoader: SettingsLoader,
public navigationLoader: NavigationLoader) { }
public settings(): Observable<any> {
return this.settingsLoader.retrieveSettings();
}
public navigation(): Observable<any> {
return this.navigationLoader.retrieveNavigation();
}
}
这是SettingsLoader 类,NavigationLoader 看起来完全一样。从设计的角度来看,它们必须是单独的类:
export abstract class SettingsLoader {
abstract retrieveSettings(): Observable<any>;
}
我的单元测试看起来像这样:
describe('ThemeConfigService', () => {
let service: ThemeConfigService;
let router: Router;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule.withRoutes([])
],
providers: [
Platform,
SettingsService,
SettingsLoader,
NavigationLoader
]
});
router = TestBed.inject(Router);
service = TestBed.inject(ThemeConfigService);
});
it('should be created', async(inject([Platform, Router, SettingsService, SettingsLoader, NavigationLoader],
(platform: Platform, router: Router, settings: SettingsService, settingsLoader: SettingsLoader, navigationLoader: NavigationLoader) => {
expect(service).toBeTruthy();
})));
});
Karma 返回的错误是:
TypeError: this.settingsLoader.retrieveSettings is not a function
which to me proves that it cannot resolve the abstract classes.
出于这个原因,我继续创建了这样的东西:
export class SettingsFakeLoader extends SettingsLoader {
retrieveSettings(): Observable<any> {
return of({});
}
}
并尝试使用这些更改 SettingsLoader 和 NavigationLoader 类的注入,然后 Karma 回复:
NullInjectorError: R3InjectorError(DynamicTestModule)[ThemeConfigService -> SettingsService -> SettingsLoader -> SettingsLoader]:
NullInjectorError: No provider for SettingsLoader!
theme-config.service.spec.ts 文件修改后的beforeEach:
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
RouterModule,
RouterTestingModule.withRoutes([])
],
providers: [
Platform,
SettingsService,
SettingsFakeLoader,
NavigationFakeLoader
]
});
router = TestBed.inject(Router);
service = TestBed.inject(ThemeConfigService);
});
通常,我不会尝试测试我认为如此复杂的东西。也许我只是没有看到“解决方案”。
这个问题的答案会很有用,因为我稍后会在这个应用程序的开发过程中解决类似的场景。
【问题讨论】:
标签: angular typescript unit-testing karma-jasmine