16

I use unit testing with karma with angular 2. I added Router in my service and but when I write test case for that it through me following error.

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

here is code

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();
      });

  });

});

I used Routing in this service to navigate path.

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')}

    );
  }



}

when I run karma start this test case failed with this error.

 ✖ 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
  • I think you do not need to add Router in providers. Try after removing it Commented Oct 3, 2016 at 6:32

1 Answer 1

22

If you don't care to do any actual routing in the test, you can just create a mock for it

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

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

Then in your test maybe you just want to make sure that the navigate method is called. You can do

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

If you do want to test real navigation, then you should use the RouterTestingModule to add all the router providers and directives.

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

TestBed.configureTestingModule({
  imports: [
    RouterTestingModule.withRoutes([{path: '', component: BlankCmp}, {path: 'simple', component: SimpleCmp}])
  ]
})
Sign up to request clarification or add additional context in comments.

1 Comment

Adding RouterTestingModule to the test's import array worked for me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.