У меня есть служба, для которой требуется зависимость от другой службы, которая, в свою очередь, требует зависимости от двух абстрактных классов.
(ThemeConfigService -> (SettingsService -> SettingsLoader, NavigationLoader))
Я дошел до того, что тест не прошел, потому что он не может найти методы, предоставляемые через абстрактные классы (не исключение функций).
Я не уверен, как мне это пройти, различные онлайн-поиски не оказались очень полезными.
Вот служба настройки темы, для которой я пытаюсь выполнить sh тест "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();
})));
});
Ошибка, возвращаемая Кармой:
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);
});
Обычно я бы не пытался протестировать то, что мне кажется сложным. Может быть, я просто не вижу «решения».
Любая помощь будет принята с благодарностью, так как у меня будет похожий сценарий, который будет решен позже в процессе разработки этого приложения.