我正在将oppia(https://github.com/oppia/oppia)的代码库从AngularJS迁移到Angular2 +。我目前正在迁移服务,之后我将迁移指令/组件。服务迁移的顺序是依存关系,即如果service3依赖于service2,service2依赖于service1-我将先迁移service1,然后再迁移service2,最后是service3。
我面临的问题是在AngularJS服务的单元测试中使用(迁移的)Angular服务。当前,我们处于混合状态,即同时使用AngularJS和Angular。我正在写一条声明来降级所有已升级到Angular的服务,例如:
angular.module('oppia').factory(
'UpgradedServices',
downgradeInjectable(UpgradedServices));
现在,参考此答案https://stackoverflow.com/a/48668591/12141840,,如果您使用的是downgradeModule,则在需要渲染第一个角度分量时,angularjs会懒惰地引导angular模块。在此之前,由于未初始化angular模块,因此如果您使用downgradeInjectable访问angularjs内部的任何angular服务,这些服务也将不可用。
对于组件,我们已如答案中所述强制进行了自举。问题在于运行服务的单元测试。因此,假设service3使用service2,service2使用service1。我将service1迁移到angular(最后是降级语句)。在第一个组件加载之前,service1对service2不可用,因此在单元测试运行时不可用(未加载任何组件以供单元测试运行)。我们不能按原样使用service1来进行service2的单元测试。
我发现一个解决方案是在其他服务(service2)的单元测试中注入{1}之类的service1。这样可以修复错误(第一个问题-这是正确的方法吗?)。但是,现在说我已经迁移了UtilsService,它已在许多服务中使用,并且有孩子(使用这些服务的其他人)-我必须在大约200个服务测试中添加$provide.value('service1', new service1())
(*规格)。然后,我们有了AlertsService,该服务再次被许多服务使用。我必须在使用它的所有服务以及依赖于所有这些服务的服务的test(* spec.ts)中再次添加$provide.value('UtilsService', new UtilsService())
。需要明确的是,如果A使用B,而B使用C,那么如果C进行了迁移,我也必须在A的测试中提供C(因为A使用B,而B使用C,并且在任何地方都没有C的实例)该流程)。
解决此问题的一种方法是添加一个服务名称UpgradedService.ts,如下所示:
$provide.value('AlertsService': new AlertsService())
,然后在AngularJS服务的所有其他* Spec.ts中使用此服务,而不是在自己到处写$ provide.value。这就是其中一种规格的外观(在beforeEach()中添加)。
import {} // statements
@Injectable({
providedIn: 'root'
})
export class UpgradedServices {
/* eslint-disable quote-props */
upgradedServices = {
'UtilsService': new UtilsService(),
'AlertsService': new AlertsService(new LoggerService()),
'ValidatorsService': new ValidatorsService(
new AlertsService(new LoggerService()), new AppConstants())
};
/* eslint-enable quote-props */
}
angular.module('oppia').factory(
'UpgradedServices',
downgradeInjectable(UpgradedServices));
第二个问题:这很好吗?或者有简单的方法来做所有这些事情吗?
第三个问题:很难在UpgradedService.ts中编写所有构造函数参数。看一下我们要嵌套的ValidatorService构造函数。我觉得随着我进一步迁移服务将变得更加困难,将有很长的嵌套构造函数参数。
这是一篇很长的文章:),我试图解释我的所有努力。谢谢!