Angularアップデート後(8→9)にテストが落ちる

困っていること

Angularを8から9にバージョンアップした後に自動テストを実行したところ、以下の様なエラーが至る所で発生しています。

エラーが起きるテストコード(hoge.component.spec.ts)

it("HogeComponent-010", fakeAsync(() => {
:
  TestBed.configureTestingModule({
      declarations: [HogeComponent],
      providers: [
        {
          provide: FugaService,
          useValue: fugaStubService
        },
        {
          provide: PiyoService
        }
      ],
    }).compileComponents();
:
}));

エラー内容

NullInjectorError: R3InjectorError(DynamicTestModule)[PiyoService -> HttpClient -> HttpClient]: 
NullInjectorError: No provider for HttpClient!
error properties: Object({ ngTempTokenPath: null, ngTokenPath: [ 'PiyoService', 'HttpClient', 'HttpClient' ] })
    at <Jasmine>
    at NullInjector.get (http://localhost:9876/packages/core/src/di/injector_compatibility.ts:231:21)
    at R3Injector.get (http://localhost:9876/packages/core/src/di/r3_injector.ts:220:27)
    at R3Injector.get (http://localhost:9876/packages/core/src/di/r3_injector.ts:220:27)
    at injectInjectorOnly (http://localhost:9876/packages/core/src/di/injector_compatibility.ts:97:29)
    at Module.ɵɵinject (http://localhost:9876/packages/core/src/di/injector_compatibility.ts:116:10)

providersに指定したクラスについて、FugaServiceのようにuseValueを指定していればエラーは起こらないようです。
PiyoServiceのようにuseValueが無い箇所でエラーが発生しています。


質問事項

  1. バージョンアップにより、useValueを指定しないとエラーが起きるようになったのはなぜか。
  2. どうすれば事象をスムーズに解決できるか。
    (1クラスずつuseValueを指定していけば解消はできそうなのですが、数が多いため何か一括して解決できるような手段がないかを知りたいです。)

補足

先日Angular10がリリースされたので、最終的には10までバージョンアップを行いたいです。
当たり前かもしれませんが、この状態で10にバージョンを上げても、同じ事象が発生したままでした。

1 Likes

1.について

おそらく本来は記述的に間違いだったのがv9以降は厳密に書かないとエラーではじくようになったと予想します。正しくは↓ですね。

{ provide: PiyoService, useClass: PiyoService }

PiyoServiceがいわゆるAngularのサービスならproviders配列に直接PiyoServiceを突っ込んでも問題なく動くはずです。

2.について

直接突っ込むだけになったので置換するだけでokそうです。

2 Likes

ukyoさん
ご回答ありがとうございます。

ご提案頂いたとおり、

{ provide: PiyoService, useClass: PiyoService }

にテストを書き替えて実行してみたのですが、同様のエラーが出たままでした。

以下の通り、useValueを用いればエラーとならない状態です。

{ provide: PiyoService, useValue: PiyoService }

DIの仕方の問題の様なのですが、何か原因にお心あたりがあればご教示いただきたく。

あ!すいません。エラー内容をよくみると HttpClient がないらしいので、HttpClientModuleをインポートする必要がありそうです。 https://angular.jp/api/common/http

TestBed.configureTestingModule({
  imports: [HttpClientModule],
  // ...
}).compileComponents();

ただ、これは実際にリクエストが飛ぶ処理が走るとそれはそれでエラーになるので https://angular.jp/api/common/http/testing/HttpClientTestingModule を使ったりspyOnあたりでリクエストが飛ばないようにする必要があります。

1 Likes

解決策にチェックをつけたつもりがついていませんでした…
おかげさまで事象を無事に解決することができました。
ご助言ありがとうございました。

1 Likes