独自のシリアライザーとその他の機能を使用しながら、カスタムAPIクエリを処理できるようにApiService
クラスを作成しました。
ApiService
のコンストラクタシグネチャは次のとおりです。
constructor(metaManager: MetaManager, connector: ApiConnectorService, eventDispatcher: EventDispatcher);
MetaManager
は、APIのメタデータを処理する注入可能なサービスです。ApiConnectorService
は、カスタムヘッダーと署名システムを追加するためにHttp
をラップするサービスです。EventDispatcher
は、基本的にはTypeScriptのSymfonyのイベントディスパッチャーシステムです。ApiService
をテストするとき、beforeEach
で初期化を行います。
beforeEach(async(() => {
TestBed.configureTestingModule({
imports : [
HttpModule
],
providers: [
ApiConnectorService,
ApiService,
MetaManager,
EventDispatcher,
OFF_LOGGER_PROVIDERS
]
});
}));
そしてそれは正常に動作します。
次に、ApiConnectorService
用の2番目のspecファイルを、次のbeforeEach
とともに追加します。
beforeEach(async(() => {
TestBed.configureTestingModule({
imports : [HttpModule],
providers: [
ApiConnectorService,
OFF_LOGGER_PROVIDERS,
AuthenticationManager,
EventDispatcher
]
});
}));
そして、すべてのテストはこのエラーで失敗します:
エラー:ApiServiceのすべてのパラメーターを解決できません:(MetaManager、?、EventDispatcher)。
api-connector-service.spec.ts
(ApiConnectorService
のspecファイル)を削除すると、ApiService
のテストは成功します。api-service.spec.ts
(ApiService
のspecファイル)を削除すると、ApiConnectorService
のテストは成功します。なぜこのエラーが発生するのですか? 2つのファイル間のコンテキストが競合しているようで、これを修正する理由と方法がわかりません。
テスト環境では、Http
サービスをHttpModule
から解決できないためです。プラットフォームブラウザに依存します。とにかく、テスト中にXHRを呼び出そうとしてもいけません。
このため、AngularはMockBackend
サービスに使用するHttp
を提供します。このモックバックエンドを使用して、テストで接続をサブスクライブします。各接続が行われたときに応答をモックします。
ここにあなたが仕事をすることができる短い完全な例があります
import { Injectable } from '@angular/core';
import { async, inject, TestBed } from '@angular/core/testing';
import { MockBackend, MockConnection } from '@angular/http/testing';
import {
Http, HttpModule, XHRBackend, ResponseOptions,
Response, BaseRequestOptions
} from '@angular/http';
@Injectable()
class SomeService {
constructor(private _http: Http) {}
getSomething(url) {
return this._http.get(url).map(res => res.text());
}
}
describe('service: SomeService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
{
provide: Http, useFactory: (backend, options) => {
return new Http(backend, options);
},
deps: [MockBackend, BaseRequestOptions]
},
MockBackend,
BaseRequestOptions,
SomeService
]
});
});
it('should get value',
async(inject([SomeService, MockBackend],
(service: SomeService, backend: MockBackend) => {
backend.connections.subscribe((conn: MockConnection) => {
const options: ResponseOptions = new ResponseOptions({body: 'hello'});
conn.mockRespond(new Response(options));
});
service.getSomething('http://dummy.com').subscribe(res => {
console.log('subcription called');
expect(res).toEqual('hello');
});
})));
});
この問題は、選択した回答で実際に解決されたわけではなく、テストを書くための推奨事項にすぎず、むしろコメントにあります。リンクをたどってそこを検索する必要があります。同じエラーで別の問題が発生したため、ここで両方のソリューションを追加します。
次のようなバレル(index.tsまたはマルチエクスポートファイル)がある場合:
_export * from 'my.component' // using my.service via DI
export * from 'my.service'
_
その後、EXCEPTION: Can't resolve all parameters for MyComponent: (?)
のようなエラーが発生する可能性があります。
修正するには、コンポーネントの前にサービスをエクスポートする必要があります。
_export * from 'my.service'
export * from 'my.component' // using my.service via DI
_
undefined
サービスのインポートを引き起こす_circular dependency
_により、同じエラーが発生する可能性があります。確認するには、console.log(YourService)
をインポートした後(テストファイルで-問題が発生している場所)。定義されていない場合は、index.tsファイル(バレル)を作成して、サービスとそれを使用するファイル(コンポーネント/効果/テストするもの)の両方をエクスポートしている可能性があります-両方がエクスポートされているインデックスファイルからサービスをインポートする(完全な円にする)。
そのファイルを見つけ、必要なサービスをインデックスではなく_your.service.ts
_ファイルから直接インポートします。