Angular 2单元测试:无法解析Router的所有参数

时间:2016-10-03 06:24:47

标签: unit-testing angular karma-runner angular2-routing

我使用带有角度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启动时,此测试用例因此错误而失败。

 ✖ 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)

1 个答案:

答案 0 :(得分:19)

如果你不想在测试中做任何实际的路由,你可以为它创建一个模拟

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

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

然后在您的测试中,您可能只想确保调用navigate方法。你可以做到

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

如果您想要测试真实导航,那么您应该使用RouterTestingModule添加所有路由器提供程序和指令。

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

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