おそらく私の間違いで解決できない迷惑なエラーがあります。私は単純なコンポーネントを持っていますが、これは実際には 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();
}
私のコンポーネントですが、これはテストのみです。アプリでは正常に動作します。私のテストでは、何らかの理由で関数がコンストラクターのパラメーターに到達できません。
ここに一種のスタック...