[Angular, Jest] TypeError: Cannot read property 'ɵprov' of undefined のエラーを解決
要約
Angularのサービスクラスに対するテストコードを作っていたとき、以下のエラーでハマりました。
TypeError: Cannot read property 'ɵprov' of undefined
または
Can't resolve all parameters for HeroService: (?).
結論から言うと、原因は分かっていないのですが、サービスクラスの@Injectable
内部の記述を以下のように変更することで解消しました。
@Injectable({
- providedIn: 'root',
+ providedIn: 'root'
})
export class HeroService {
カンマ消しただけです・・・。
原因分かる方がいらっしゃったら、コメント欄で教えていただけると幸いです。
(2020.11.15 追記)
解決しました。(やはりカンマは関係ありませんでした。)
tsconfig
のcompilerOptions
に以下のパラメータを追加したらエラーが解消されました。
{
"compilerOptions": {
+ "emitDecoratorMetadata": true
},
}
こちらのjest-preset-angularによると、Angular8以上はCLIの設定によってメタデータが欠ける可能性があるそうです。
With Angular 8 and higher, a change to the way the Angular CLI works may be causing your metadata to be lost
この設定を追加して実行すると、テストが通りました。
ちなみに、設定を変更したのに変わらない場合は、キャッシュを無効にして実行すると良いかもしれません。
$ jest hero.service --no-cache
(追記おわり)
環境
$ ng --version
Angular CLI: 10.1.7
Node: 12.16.1
OS: win32 x64
Angular: 10.1.6
... animations, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router
Ivy Workspace: Yes
Package Version
---------------------------------------------------------
@angular-devkit/architect 0.1001.7
@angular-devkit/build-angular 0.1002.0
@angular-devkit/core 10.1.7
@angular-devkit/schematics 10.1.7
@angular/cli 10.1.7
@schematics/angular 10.1.7
@schematics/update 0.1001.7
rxjs 6.6.3
typescript 4.0.5
経緯
Angularのチュートリアル「Tour Of Heroes」の「4. サービスの追加」にあるサンプルコードに対してテストコードを実装しようとしていました。
テスト対象のクラスは以下。ダウンロードしたファイルそのままです。
import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
import { Hero } from './hero';
import { HEROES } from './mock-heroes';
import { MessageService } from './message.service';
@Injectable({
providedIn: 'root',
})
export class HeroService {
constructor(private messageService: MessageService) { }
getHeroes(): Observable<Hero[]> {
// TODO: send the message _after_ fetching the heroes
this.messageService.add('HeroService: fetched heroes');
return of(HEROES);
}
}
それに対して、以下のようなテストコードを実装。
import { TestBed } from '@angular/core/testing';
import { HeroService } from 'src/app/hero.service';
describe('TestHeroService', () => {
let heroService: HeroService;
beforeEach(() => {
TestBed.configureTestingModule({});
heroService = TestBed.inject(HeroService);
});
it('should be created', () => {
expect(heroService).toBeTruthy();
});
});
インスタンス化されることをサクッとテストして、メソッドのテストを書くつもりだったのですが、冒頭の通り
TypeError: Cannot read property 'ɵprov' of undefined
というエラーが発生しました。
調べてみると正しくDIができていないようなのですが、はっきりとした原因は分かりませんでした。
解決への道のり
以下のような経緯でとりあえず解決しました。
- HeroServiceにおいて、MessageServiceをDIしないようにコメントアウトした。
- エラーが解消したので、やはりDIが関係していると判断
- Angular CLIを用いて別のサービス(TestService)を作成。HeroServiceと同様にMessageServiceをDIした上で同様のテストコードを作成。
- TestServiceのテストコードが通った。
- HeroServiceとTestServiceを比較して、
providedIn
の部分が異なることを発見し、修正したらHeroServiceのテストコードが通った。
修正後のコードはこちらです。
import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
import { Hero } from './hero';
import { HEROES } from './mock-heroes';
import { MessageService } from './message.service';
@Injectable({
providedIn: 'root' // カンマを消しただけ
})
export class HeroService {
constructor(private messageService: MessageService) { }
getHeroes(): Observable<Hero[]> {
// TODO: send the message _after_ fetching the heroes
this.messageService.add('HeroService: fetched heroes');
return of(HEROES);
}
}
Author And Source
この問題について([Angular, Jest] TypeError: Cannot read property 'ɵprov' of undefined のエラーを解決), 我々は、より多くの情報をここで見つけました https://qiita.com/yuma-ito-bd/items/cd32cb57e13f56b59f18著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .