Angular 8.1.0부터 들어간 createAngularJSTestingModule 읽어보기
11994 단어 Angular
소개
Angular 9.0 출시 2020년 무슨 이야기가 얼마 전 있었습니다만, 지금도 AngularJS가 현역으로 움직이고 있는 프로젝트는 아직 있는 것이 아닐까요.
제가 참여하고 있는 프로젝트도 그 중의 하나로, 현재는 AngularJS+Angular 8의 하이브리드 구성으로 움직이고 있습니다. 지금도 절찬 이행 중입니다
이제 Angular 8.1.0 릴리스에서 createAngularJSTestingModule
와 createAngularTestingModule
가 릴리스되었음을 알고 계십니까?
AngularJS와 Angular가 하이브리드로 움직이는 환경에서 유닛 테스트를 지원하기위한 Helper function입니다.
오늘은 그 안의 createAngularJSTestingModule
에 대해 보고 싶습니다
우리 팀에서 움직이는 하이브리드 애플리케이션의 테스트가 가끔씩 통과하지 못할 수 있고, 원래 테스트에서는 어떤 일을 하고 있는지를 보고 싶었다는 것이 계기입니다.
자꾸 사용하는 곳을 설명
Angular로 작성된 Service를 downgrade하여 AngularJS에서 사용하는 경우,
테스트 중에도 하이브리드 애플리케이션을 bootstrap 해 줄 필요가있었습니다.
그러나 새로 추가된 createAngularJSTestingModule을 사용하면 더 이상 필요하지 않습니다. 테스트를 간단하게 쓸 수 있고, 고속으로 실행할 수 있게 되는 것 같습니다.
시험에서
beforeEach(module(createAngularJSTestingModule([Ng2AppModule])));
beforeEach(module(ng1AppModule.name));
라고 쓰면 AngularJS의 Injector에서 Angular의 Service를 꺼낼 수 있게 됩니다. 이런 느낌↓↓
it('should have access to the HeroesService',
inject((heroesService: HeroesService) => {
expect(heroesService).toBeDefined();
})
);
코드를 살펴보기
Angular 8.2.14의 @angular/upgrade/static/testing에서 createAngularJSTestingModule의 소스입니다.
export function createAngularJSTestingModule(angularModules: any[]): string {
return ng.module_('$$angularJSTestingModule', [])
.constant(UPGRADE_APP_TYPE_KEY, UpgradeAppType.Static) // '$$angularUpgradeAppType', 2
.factory(
INJECTOR_KEY, // '$$angularInjector'
[
$INJECTOR, // '$injector'
($injector: ng.IInjectorService) => {
TestBed.configureTestingModule({
imports: angularModules,
providers: [{provide: $INJECTOR, useValue: $injector}]
});
return TestBed.get(Injector);
}
])
.name;
}
여기서 하는 일은
- $$angularJSTestingModule
라는 AngularJS 모듈 만들기
- $$angularUpgradeAppType
라는 AngularJS constant에 2 (UpgradeAppType.Static)를 지정합니다.
- TestBed.configureTestingModule
에서 테스트 용 모듈을 생성하면서 ...
- $$angularInjector
라는 이름으로 Angular Injector
를 AngularJS에 제공합니다.
입니다. 이것만으로는 "AngularJS에서 $$angularInjector
라는 이름으로 DI하지 않는다"고 생각할지도 모릅니다만
다음으로 보여주는 downgradeInjectable
가 열쇠입니다.downgradeInjectable
는 Angular 서비스를 AngularJS에서 사용하는 데 필요한 도우미 함수입니다.
@Injectable()
export class AwesomeService { ... }
ng1App.factory('AwesomeService', downgradeInjectable(AwesomeService) as any)
라는 느낌으로 씁니다. 그것을 근거로 downgradeInjectable 구현를 보러 가면 ...
// 第2引数の downgradedModule は使っていないです
export function downgradeInjectable(token: any, downgradedModule: string = ''): Function {
const factory = function($injector: IInjectorService) {
const injectorKey = `${INJECTOR_KEY}${downgradedModule}`; // '$$angularInjector'
// isFunction = (t) => typeof t === 'function'
// なので、ここではgetTypeNameの結果 'AwesomeService' が使われます(ログ用)
const injectableName = isFunction(token) ? getTypeName(token) : String(token);
const attemptedAction = `instantiating injectable '${injectableName}'`;
// ただしくupgradeされているアプリケーションかチェックする(雑に書いてます)
// createAngularJSTestingModule内で '$$angularUpgradeAppType' を 2 として定義したのは
// ここのチェックを通すためだと思われる。本来であればbootstrapをしないと通せない場所。
validateInjectionKey($injector, downgradedModule, injectorKey, attemptedAction);
// AngularJSの世界に定義してあるAngularのInjectorを取得する
const injector: Injector = $injector.get(injectorKey);
return injector.get(token); // そこからAwesomeServiceを取得して返す
};
(factory as any)['$inject'] = [$INJECTOR];
return factory;
}
라는 느낌이 듭니다.
Angular downgradeInjectable
는 응용 프로그램의 bootstrap이 완료되었는지 확인합니다.
여기를 통과하는 데 필요한 최소한의 작업을 수행하는 것으로 나타났습니다
후기
사실이라면, 업무에서 사용하고 있는 코드를 좋은 느낌의 샘플 프로젝트에 떨어뜨리는 것이 좋지만, 잘 테스트가 움직이지 않는 부분도 있어 포기했습니다
Angular 버전이 곧 9가 되려고 노력했지만 Angular 팀은 AngularJS에서 마이그레이션을 지원하는 도구를 계속 출시했습니다. 고마워요
Reference
이 문제에 관하여(Angular 8.1.0부터 들어간 createAngularJSTestingModule 읽어보기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/pittanko_pta/items/3ee3df9651aeae99821f
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Angular로 작성된 Service를 downgrade하여 AngularJS에서 사용하는 경우,
테스트 중에도 하이브리드 애플리케이션을 bootstrap 해 줄 필요가있었습니다.
그러나 새로 추가된 createAngularJSTestingModule을 사용하면 더 이상 필요하지 않습니다. 테스트를 간단하게 쓸 수 있고, 고속으로 실행할 수 있게 되는 것 같습니다.
시험에서
beforeEach(module(createAngularJSTestingModule([Ng2AppModule])));
beforeEach(module(ng1AppModule.name));
라고 쓰면 AngularJS의 Injector에서 Angular의 Service를 꺼낼 수 있게 됩니다. 이런 느낌↓↓
it('should have access to the HeroesService',
inject((heroesService: HeroesService) => {
expect(heroesService).toBeDefined();
})
);
코드를 살펴보기
Angular 8.2.14의 @angular/upgrade/static/testing에서 createAngularJSTestingModule의 소스입니다.
export function createAngularJSTestingModule(angularModules: any[]): string {
return ng.module_('$$angularJSTestingModule', [])
.constant(UPGRADE_APP_TYPE_KEY, UpgradeAppType.Static) // '$$angularUpgradeAppType', 2
.factory(
INJECTOR_KEY, // '$$angularInjector'
[
$INJECTOR, // '$injector'
($injector: ng.IInjectorService) => {
TestBed.configureTestingModule({
imports: angularModules,
providers: [{provide: $INJECTOR, useValue: $injector}]
});
return TestBed.get(Injector);
}
])
.name;
}
여기서 하는 일은
- $$angularJSTestingModule
라는 AngularJS 모듈 만들기
- $$angularUpgradeAppType
라는 AngularJS constant에 2 (UpgradeAppType.Static)를 지정합니다.
- TestBed.configureTestingModule
에서 테스트 용 모듈을 생성하면서 ...
- $$angularInjector
라는 이름으로 Angular Injector
를 AngularJS에 제공합니다.
입니다. 이것만으로는 "AngularJS에서 $$angularInjector
라는 이름으로 DI하지 않는다"고 생각할지도 모릅니다만
다음으로 보여주는 downgradeInjectable
가 열쇠입니다.downgradeInjectable
는 Angular 서비스를 AngularJS에서 사용하는 데 필요한 도우미 함수입니다.
@Injectable()
export class AwesomeService { ... }
ng1App.factory('AwesomeService', downgradeInjectable(AwesomeService) as any)
라는 느낌으로 씁니다. 그것을 근거로 downgradeInjectable 구현를 보러 가면 ...
// 第2引数の downgradedModule は使っていないです
export function downgradeInjectable(token: any, downgradedModule: string = ''): Function {
const factory = function($injector: IInjectorService) {
const injectorKey = `${INJECTOR_KEY}${downgradedModule}`; // '$$angularInjector'
// isFunction = (t) => typeof t === 'function'
// なので、ここではgetTypeNameの結果 'AwesomeService' が使われます(ログ用)
const injectableName = isFunction(token) ? getTypeName(token) : String(token);
const attemptedAction = `instantiating injectable '${injectableName}'`;
// ただしくupgradeされているアプリケーションかチェックする(雑に書いてます)
// createAngularJSTestingModule内で '$$angularUpgradeAppType' を 2 として定義したのは
// ここのチェックを通すためだと思われる。本来であればbootstrapをしないと通せない場所。
validateInjectionKey($injector, downgradedModule, injectorKey, attemptedAction);
// AngularJSの世界に定義してあるAngularのInjectorを取得する
const injector: Injector = $injector.get(injectorKey);
return injector.get(token); // そこからAwesomeServiceを取得して返す
};
(factory as any)['$inject'] = [$INJECTOR];
return factory;
}
라는 느낌이 듭니다.
Angular downgradeInjectable
는 응용 프로그램의 bootstrap이 완료되었는지 확인합니다.
여기를 통과하는 데 필요한 최소한의 작업을 수행하는 것으로 나타났습니다
후기
사실이라면, 업무에서 사용하고 있는 코드를 좋은 느낌의 샘플 프로젝트에 떨어뜨리는 것이 좋지만, 잘 테스트가 움직이지 않는 부분도 있어 포기했습니다
Angular 버전이 곧 9가 되려고 노력했지만 Angular 팀은 AngularJS에서 마이그레이션을 지원하는 도구를 계속 출시했습니다. 고마워요
Reference
이 문제에 관하여(Angular 8.1.0부터 들어간 createAngularJSTestingModule 읽어보기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/pittanko_pta/items/3ee3df9651aeae99821f
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
export function createAngularJSTestingModule(angularModules: any[]): string {
return ng.module_('$$angularJSTestingModule', [])
.constant(UPGRADE_APP_TYPE_KEY, UpgradeAppType.Static) // '$$angularUpgradeAppType', 2
.factory(
INJECTOR_KEY, // '$$angularInjector'
[
$INJECTOR, // '$injector'
($injector: ng.IInjectorService) => {
TestBed.configureTestingModule({
imports: angularModules,
providers: [{provide: $INJECTOR, useValue: $injector}]
});
return TestBed.get(Injector);
}
])
.name;
}
@Injectable()
export class AwesomeService { ... }
ng1App.factory('AwesomeService', downgradeInjectable(AwesomeService) as any)
// 第2引数の downgradedModule は使っていないです
export function downgradeInjectable(token: any, downgradedModule: string = ''): Function {
const factory = function($injector: IInjectorService) {
const injectorKey = `${INJECTOR_KEY}${downgradedModule}`; // '$$angularInjector'
// isFunction = (t) => typeof t === 'function'
// なので、ここではgetTypeNameの結果 'AwesomeService' が使われます(ログ用)
const injectableName = isFunction(token) ? getTypeName(token) : String(token);
const attemptedAction = `instantiating injectable '${injectableName}'`;
// ただしくupgradeされているアプリケーションかチェックする(雑に書いてます)
// createAngularJSTestingModule内で '$$angularUpgradeAppType' を 2 として定義したのは
// ここのチェックを通すためだと思われる。本来であればbootstrapをしないと通せない場所。
validateInjectionKey($injector, downgradedModule, injectorKey, attemptedAction);
// AngularJSの世界に定義してあるAngularのInjectorを取得する
const injector: Injector = $injector.get(injectorKey);
return injector.get(token); // そこからAwesomeServiceを取得して返す
};
(factory as any)['$inject'] = [$INJECTOR];
return factory;
}
사실이라면, 업무에서 사용하고 있는 코드를 좋은 느낌의 샘플 프로젝트에 떨어뜨리는 것이 좋지만, 잘 테스트가 움직이지 않는 부분도 있어 포기했습니다
Angular 버전이 곧 9가 되려고 노력했지만 Angular 팀은 AngularJS에서 마이그레이션을 지원하는 도구를 계속 출시했습니다. 고마워요
Reference
이 문제에 관하여(Angular 8.1.0부터 들어간 createAngularJSTestingModule 읽어보기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/pittanko_pta/items/3ee3df9651aeae99821f텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)