正在测试具有抽象类依赖性的Angular服务

问题描述 投票:0回答:1

我有一个服务,该服务需要对另一个服务的依赖,而该服务又需要对两个抽象类的依赖。

(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({});
    }
}

[并尝试使用它们更改SettingsLoaderNavigationLoader类的注入,然后因果响应:

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);
});

通常,我不会尝试测试我认为如此复杂的事物。也许我只是没有看到“解决方案”。

任何帮助将不胜感激,因为我将有一个类似的情况来解决此应用程序开发的问题。

angular typescript unit-testing karma-jasmine
1个回答
0
投票

我走了实例化路线,而不是依赖于依赖注入。这可能不是一个可行的解决方案,并且仍然希望有更好的方法来回答原始问题。

[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();
  });
});
© www.soinside.com 2019 - 2024. All rights reserved.