4

おそらく私の間違いで解決できない迷惑なエラーがあります。私は単純なコンポーネントを持っていますが、これは実際には Web アプリケーションのトップバー要素に他なりません。

ご覧のとおり、このコンポーネントには依存関係が 1 つしかなく、UserService非常に単純に使用されます。

import { Component, OnInit } from '@angular/core';
import { MdButton } from '@angular2-material/button';
import { MdIcon , MdIconRegistry} from '@angular2-material/icon';
import { UserService } from '../services/index';
import { RouteConfig, ROUTER_DIRECTIVES, Router, ROUTER_PROVIDERS 
  } from '@angular/router-deprecated';


@Component({
  moduleId: module.id,
  selector: 'top-bar',
  templateUrl: 'top-bar.component.html',
  styleUrls: ['top-bar.component.css'],
  providers: [MdIconRegistry, UserService, ROUTER_PROVIDERS],
  directives: [MdButton, MdIcon, ROUTER_DIRECTIVES]
})
export class TopBarComponent implements OnInit {

  constructor(private userService: UserService) {
    this.userService = userService;
  }

  ngOnInit() {
  }

  /**
   * Call UserService and logout() method
   */
  logout() {
    this.userService.logout();
  }

}

このサービスにはいくつかの依存関係 (ルーターなど) もあるため、beforeEachProvidersご覧のとおり、メソッドでそれらを提供する必要がありました。

import {
  beforeEach,
  beforeEachProviders,
  describe,
  expect,
  it,
  inject,
} from '@angular/core/testing';
import { TopBarComponent } from './top-bar.component';
import {
  Router, RootRouter, RouteRegistry, ROUTER_PRIMARY_COMPONENT
} from '@angular/router-deprecated';
import { provide } from '@angular/core';
import { SpyLocation } from '@angular/common/testing';
import { UserService } from '../services/index';

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

  beforeEachProviders(() => [
      RouteRegistry,
      provide(Location, { useClass: SpyLocation }),
      provide(ROUTER_PRIMARY_COMPONENT, { useValue: TopBarComponent }),
      provide(Router, { useClass: RootRouter }),
      UserService,
      TopBarComponent
  ]);

  it('should inject the component', inject([TopBarComponent],
      (component: TopBarComponent) => {
    expect(component).toBeTruthy();
  }));

});

テストを実行すると、次のエラー メッセージが表示されます。

Chrome 51.0.2704 (Mac OS X 10.11.5) コンポーネント: TopBar はコンポーネントを注入する必要があります 失敗 エラー: ロケーションのプロバイダーがありません! (TopBarComponent -> UserService -> Router -> Location) エラー: DI 例外[......]

まず、ロケーション プロバイダーが提供されていることがわかります。そして二次的に、なぜ私のテストでは、テストされたコンポーネントサービスに使用される依存関係も提供 (または注入) する必要があるのですか?

たとえば、上記のテストから Router を削除すると、コンポーネントが Router を使用していなくても、使用されているサービスが使用しているため、エラーが発生します。それでは、テストだけでなく、コンポーネントでも同じエラーを受け取るべきではありませんか?

更新 - コードとエラー メッセージの変更

仕様を次のように変更することで、このエラーの発生を止めることができました。

import {
  beforeEach,
  describe,
  expect,
  it,
} from '@angular/core/testing';
import { TopBarComponent } from './top-bar.component';
import { UserService } from '../services/index';
import {
  Router
} from '@angular/router-deprecated';
import { Http } from '@angular/http';
import { AuthHttp } from 'angular2-jwt';

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

  let router: any = Router;
  let authHttp: any = AuthHttp;
  let http: any = Http;
  let component: TopBarComponent;
  let service: UserService = new UserService(router, authHttp, http);

  beforeEach(() => {
      component = new TopBarComponent(service);
  });

  it('logout function should work ', () => {
    let logout = component.logout;
    logout();
    expect(localStorage.getItem('token')).toBe(null);
  });

});

しかし、私のコンポーネントからこのエラーが発生していることを知っています:

TypeError: 未定義のプロパティ 'userService' を読み取れません

言及されたエラーはこの関数にあります:

logout() {
  this.userService.logout();
}

私のコンポーネントですが、これはテストのみです。アプリでは正常に動作します。私のテストでは、何らかの理由で関数がコンストラクターのパラメーターに到達できません。

ここに一種のスタック...

4

2 に答える 2