web-dev-qa-db-ja.com

Angular 2ユニットテスト:ルーターのすべてのパラメーターを解決できません

angular 2.でカルマを使用した単体テストを使用します。サービスにルーターを追加しましたが、そのためのテストケースを作成すると、次のエラーが表示されます。

 Error: Can't resolve all parameters for Router: (?, ?, ?, ?, ?, ?, ?, ?).

ここにコードがあります

spec.ts

import 'rxjs/add/operator/map';
import { Http, BaseRequestOptions, Response, ResponseOptions,ConnectionBackend } from '@angular/http';
import { MockBackend, MockConnection } from '@angular/http/testing';
import { GlobalUtils } from './global.utils';
import {  Router} from '@angular/router';

import { TestBed, inject } from '@angular/core/testing';



describe('Global Utils : Meta urls API', () => {
  let emptyMetaUrl = {};

  let metaUrl = {
    LOGIN: '/operator/login',
    META_API: '/meta-api'
  };

  beforeEach(()=>TestBed.configureTestingModule({

    providers: [
      Router,
      GlobalUtils,
      BaseRequestOptions,
      MockBackend,
      {
        provide: Http,
        useFactory: function (backend:ConnectionBackend, defaultOptions:BaseRequestOptions) {
          return new Http(backend, defaultOptions);
        },
        deps: [MockBackend, BaseRequestOptions]
      },

    ]
  }));


  let subject:GlobalUtils = null;
  let backend:MockBackend = null;
  let http:Http = null;

  beforeEach(inject([GlobalUtils, MockBackend, Http], (_globalUtils:GlobalUtils, mockBackend:MockBackend,_http:Http) => {
    subject = _globalUtils;
    backend = mockBackend;
    http = _http;
  }));

  it('Should have get Meta urls', (done) => {

    backend.connections.subscribe((connection:MockConnection)=> {
      let options = new ResponseOptions({
        body: JSON.stringify(metaUrl)
      });
      connection.mockRespond(new Response(options));
    });

    http
      .get(subject.metaUrl)
      .subscribe((response) => {

         subject.getMetaUrls();   //   in this routing is use 

        expect(GlobalUtils.saveUrl).toEqual(metaUrl);
        done();
      });

  });

});

このサービスでルーティングを使用してパスをナビゲートしました。

service.ts

import {Injectable} from '@angular/core';
import { Router}  from '@angular/router';
import {Http, Headers,Response} from '@angular/http';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';

@Injectable()
export class GlobalUtils {
  static saveUrl = { };

  head:Headers = new Headers();
  hostUrl:string = 'http://192.168.0.103:8000/';
  metaUrl:string = 'urls-metadata/';

  // constructor declare
  constructor(public _http:Http,public _router:Router) {
    this.head.append('Content-Type', 'application/json');
  }

  /*
   * this function is used for Http GET Request
   * */
  urlGet(url:string) {
    let headers = this.head;
    return this._http.get(this.hostUrl + url, {headers: headers})
      .map(res => res.json())
      .map((res) => {
        return res;
      });
  }

  /*
   * this function is used to GET all API url
   * */
  getMetaUrls():any{
    let url = this.metaUrl;
    this.urlGet(url).subscribe(
      (result) => {
        console.log('result = '+JSON.stringify(result));
          if (result) {
          GlobalUtils.saveUrl = result;
            console.log('get Meta urls response = '+ result.status)
          }
       },

      (error)=> {
         this._router.navigate(['page-error']);
        console.log('get Meta urls error = '+ error.status + " data =" +JSON.stringify(error))
      },

      ()=>{console.log('get Meta url is successfully')}

    );
  }



}

karma startを実行すると、このテストケースはこのエラーで失敗しました。

 ✖ Should have get Meta urls
      Chrome 52.0.2743 (Linux 0.0.0)
    Error: Can't resolve all parameters for Router: (?, ?, ?, ?, ?, ?, ?, ?).
        at CompileMetadataResolver.getDependenciesMetadata (webpack:///~/@angular/compiler/bundles/compiler.umd.js:14404:0 <- config/spec-bundle.js:53297:22)
        at CompileMetadataResolver.getTypeMetadata (webpack:///~/@angular/compiler/bundles/compiler.umd.js:14301:0 <- config/spec-bundle.js:53194:29)
        at webpack:///~/@angular/compiler/bundles/compiler.umd.js:14448:0 <- config/spec-bundle.js:53341:44
        at Array.forEach (native)
        at CompileMetadataResolver.getProvidersMetadata (webpack:///~/@angular/compiler/bundles/compiler.umd.js:14428:0 <- config/spec-bundle.js:53321:22)
        at CompileMetadataResolver.getNgModuleMetadata (webpack:///~/@angular/compiler/bundles/compiler.umd.js:14181:0 <- config/spec-bundle.js:53074:61)
        at RuntimeCompiler._compileComponents (webpack:///~/@angular/compiler/bundles/compiler.umd.js:16803:0 <- config/spec-bundle.js:55696:50)
        at RuntimeCompiler._compileModuleAndAllComponents (webpack:///~/@angular/compiler/bundles/compiler.umd.js:16747:0 <- config/spec-bundle.js:55640:40)
        at RuntimeCompiler.compileModuleAndAllComponentsSync (webpack:///~/@angular/compiler/bundles/compiler.umd.js:16735:0 <- config/spec-bundle.js:55628:24)
        at TestingCompilerImpl.compileModuleAndAllComponentsSync (webpack:///~/@angular/compiler/bundles/compiler-testing.umd.js:758:0 <- config/spec-bundle.js:38833:36)
15
Rahul dev

テストで実際のルーティングを行う必要がない場合は、モックを作成できます

let mockRouter = {
  navigate: jasmine.createSpy('navigate')
} 

TestBed.configureTestingModule({
  providers: [
    { provide: Router, useValue: mockRouter }
  ]
})

次に、テストでnavigateメソッドが呼び出されていることを確認したいだけかもしれません。できるよ

expect(mockRouter.navigate).toHaveBeenCalledWith(['/router']);

doで実際のナビゲーションをテストする場合は、RouterTestingModuleを使用してすべてのルータープロバイダーとディレクティブを追加する必要があります。

import { RouterTestingModule } from '@angular/router/testing';

TestBed.configureTestingModule({
  imports: [
    RouterTestingModule.withRoutes([{path: '', component: BlankCmp}, {path: 'simple', component: SimpleCmp}])
  ]
})
20
Paul Samsotha