我有一个服务,该服务需要对另一个服务的依赖,而该服务又需要对两个抽象类的依赖。
(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
类的注入,然后因果响应:
NullInjectorError: R3InjectorError(DynamicTestModule)[ThemeConfigService -> SettingsService -> SettingsLoader -> SettingsLoader]:
NullInjectorError: No provider for SettingsLoader!
[beforeEach
文件的修改后的theme-config.service.spec.ts
:
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
RouterModule,
RouterTestingModule.withRoutes([])
],
providers: [
Platform,
SettingsService,
SettingsFakeLoader,
NavigationFakeLoader
]
});
router = TestBed.inject(Router);
service = TestBed.inject(ThemeConfigService);
});
通常,我不会尝试测试我认为如此复杂的事物。也许我只是没有看到“解决方案”。
任何帮助将不胜感激,因为我将有一个类似的情况来解决此应用程序开发的问题。
我走了实例化路线,而不是依赖于依赖注入。这可能不是一个可行的解决方案,并且仍然希望有更好的方法来回答原始问题。
[describe
文件的更新的theme-config.service.spe.ts
:
describe('ThemeConfigService', () => {
let service: ThemeConfigService;
let sLoader: SettingsLoader;
let nLoader: NavigationLoader;
let sService: SettingsService;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule.withRoutes([])
],
providers: [
ThemeConfigService,
SettingsService,
SettingsLoader,
NavigationLoader
]
});
let platform = TestBed.inject(Platform);
let router = TestBed.inject(Router);
sLoader = new SettingsFakeLoader();
nLoader = new NavigationFakeLoader();
sService = new SettingsService(sLoader, nLoader);
service = new ThemeConfigService(platform, router, sService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});