/var/log/messages

Jun 8, 2018 - 4 minute read - Comments - Angular

Testing Dependency Injection

以下なドキュメント機械翻訳控えを投入。

Testing Dependency Injection

Learning Objectives

  • Angularアプリケーションでインジェクタをテスト用に設定する方法を理解してください。
  • テストのためにトークンを解決するために使用できるさまざまな方法を理解する。

Resolving via TestBed

これは今までこのセクションで依存関係を注入した方法です。

TestBedはダミーのAngular Moduleとして機能し、次のような一連のプロバイダを含むように設定できます。

TestBed.configureTestingModule({
  providers: [AuthService]
});

次に、TestBedに内部インジェクタを使用してトークンを依存関係に解決するように依頼することができます。

testBedService = TestBed.get(AuthService);

私たちのテスト仕様のほとんどが同じ依存関係を同じように mock する必要があるならば、beforeEach関数で一度解決して、それを mock することができます。

Resolving via the inject function

it('Service injected via inject(...) and TestBed.get(...) should be the same instance',
    inject([AuthService], (injectService: AuthService) => {
      expect(injectService).toBe(testBedService);
    })
);

inject関数はテスト仕様関数をラップしますが、TestBedの親インジェクタを使用して依存関係を注入することもできます。

私たちはそれを好きに使う:

inject(
  [token1, token2, token2],
  (dep1, dep2, dep3) => { }
)

最初のパラメータは依存関係を解決したいトークンの配列で、2番目のパラメータは引数が解決された依存関係である関数です。

注射機能の使用:

各仕様関数がどのような依存関係を使用するかを明確にします。

それぞれのテスト仕様が異なるモックとスパイスを必要とする場合、これはテストスイートごとに1回解決するより良い解決策です。

重要 これは最終的に次のような関数デコレータになります: @Inject (dep1: Token1, dep2: Token2) => { … }

Overriding the components providers

TestBed経由でコンポーネントを作成する前に、そのコンポーネントをオーバーライドすることができます。 私たちがAuthServiceのようなモックを持っていると想像してみましょう:

class MockAuthService extends AuthService {
  isAuthenticated() {
    return 'Mocked';
  }
}

このような虚偽のAuthServiceを使用するように、コンポーネントプロバイダをオーバーライドすることができます。

TestBed.overrideComponent(
    LoginComponent,
    {set: {providers: [{provide: AuthService, useClass: MockAuthService}]}}
);

構文は非常に具体的で、MetaDataOverrideと呼ばれ、プロパティの設定、追加、削除を行うことができます。 setを使用して、providers配列を設定した値に完全に置き換えます。

Resolving via the component injector

今、私たちのコンポーネントは独自のプロバイダで構成されているので、子インジェクタがあります。

コンポーネントが独自のインジェクタを持っているのでコンポーネントが作成されると、AuthService自体が解決され、そのリクエストを親のTestBedインジェクタに転送しません。

コンポーネントインジェクタを使用して解決する必要があるコンポーネントコンストラクタに渡された依存関係の同じインスタンスを取得したい場合は、次のようにコンポーネントフィクスチャを使用してそれを実行できます。

componentService = fixture.debugElement.injector.get(AuthService);

上記のコードは、コンポーネントの子インジェクタを使用してトークンを解決します。

Summary

私たちは、いくつかの方法を使ってテストの依存関係を解決することができます。

通常はbeforeEach関数でテストベッド自体を使用して解決でき、解決された依存関係をテスト仕様で使用するために保存できます。

各テスト仕様の開始時にinject関数を使用して解決できます。

また、TestBedを使用してコンポーネントのデフォルトプロバイダをオーバーライドすることもできます。

コンポーネントの子インジェクタを使用してトークンを解決することもできます。

Listing

http://plnkr.co/edit/PeWgLg6nbJ6MmdG8SzVW?p=preview Listing 1. login.component.spec.ts

/* tslint:disable:no-unused-variable */
import {TestBed, ComponentFixture, inject} from '@angular/core/testing';
import {LoginComponent} from './login.component';
import {AuthService} from "./auth.service";

class MockAuthService extends AuthService {
  isAuthenticated() {
    return 'Mocked';
  }
}


describe('Component: Login', () => {

  let component: LoginComponent;
  let fixture: ComponentFixture<LoginComponent>;
  let testBedService: AuthService;
  let componentService: AuthService;

  beforeEach(() => {

    // refine the test module by declaring the test component
    TestBed.configureTestingModule({
      declarations: [LoginComponent],
      providers: [AuthService]
    });

    // Configure the component with another set of Providers
    TestBed.overrideComponent(
        LoginComponent,
        {set: {providers: [{provide: AuthService, useClass: MockAuthService}]}}
    );

    // create component and test fixture
    fixture = TestBed.createComponent(LoginComponent);

    // get test component from the fixture
    component = fixture.componentInstance;

    // AuthService provided to the TestBed
    testBedService = TestBed.get(AuthService);

    // AuthService provided by Component, (should return MockAuthService)
    componentService = fixture.debugElement.injector.get(AuthService);
  });

  it('Service injected via inject(...) and TestBed.get(...) should be the same instance',
      inject([AuthService], (injectService: AuthService) => {
        expect(injectService).toBe(testBedService);
      })
  );

  it('Service injected via component should be and instance of MockAuthService', () => {
    expect(componentService instanceof MockAuthService).toBeTruthy();
  });
});

Testing Asynchronous Code Testing Components

comments powered by Disqus