9

Ich habe Probleme, einen Mock für eine RouteParams-Abhängigkeit in einen Test für eine Angular2-Komponente einzufügen. Mein allgemeiner Gedanke ist, dass mir einige Anbieter fehlen könnten.Angular2 - verspottete RouteParams im Test

die Tests fehlschlagen mit:

 
Cannot resolve all parameters for 'RouteParams'(?). Make sure that all the parameters are decorated with Inject 
or have valid type annotations and that 'RouteParams' is decorated with Injectable. 

Weiß jemand, was das Problem sein könnte?

import { 
    it, 
    inject, 
    injectAsync, 
    describe, 
    beforeEach, 
    beforeEachProviders, 
    TestComponentBuilder 
} from 'angular2/testing'; 

import {Component, provide} from 'angular2/core'; 
import {BaseRequestOptions, Http} from 'angular2/http'; 
import {MockBackend} from 'angular2/http/testing'; 
import {RouteParams, ROUTER_PROVIDERS, ROUTER_PRIMARY_COMPONENT} from 'angular2/router'; 

// Load the implementations that should be tested 
import {Home} from './home'; 
import {Title} from './providers/title'; 

describe('Home',() => { 
    // provide our implementations or mocks to the dependency injector 

    beforeEachProviders(() => [ 
    Title, 
    Home, 
    provide(RouteParams, { useValue: new RouteParams({ id: '1' }) }), 
    BaseRequestOptions, 
    MockBackend, 
    provide(Http, { 
     useFactory: function(backend, defaultOptions) { 
      return new Http(backend, defaultOptions); 
     }, 
     deps: [MockBackend, BaseRequestOptions] 
    }), 
    provide(RouteParams, { 
     useFactory: function() { 
      return new RouteParams({ 'id':'1' }); 
     } 
    }) 
    ]); 

    it('should have a title', inject([ Home ], (home) => { 
    expect(home.title.value).toEqual('Angular 2'); 
    })); 

    it('should have a http', inject([ Home ], (home) => { 
    expect(!!home.http).toEqual(true); 
    })); 

    it('should log ngOnInit', inject([ Home ], (home) => { 
    spyOn(console, 'log'); 
    spyOn(console, 'info'); 
    expect(console.log).not.toHaveBeenCalled(); 
    expect(console.info).not.toHaveBeenCalled(); 

    home.ngOnInit(); 
    expect(console.log).toHaveBeenCalled(); 
    expect(console.info).toHaveBeenCalledWith('1'); 
    })); 

}); 

Antwort

1

Für Menschen mit, die hier landen, obwohl sie mit arbeiten Angular4

Ich ging einfach weiter und erstellt ein Spott. Ich denke, der Trick ist, die Teile des ActivatedRoute zu verspotten, die Sie brauchen. für mich tat dies es:

import {ActivatedRoute, ParamMap} from '@angular/router'; 

/** 
* Mocking the ActivatedRoute which is injected in the Component on creation. 
* This allows for easier testing as values can be set as needed. 
*/ 
class MockActivatedRoute { 
    paramMap = Observable.of(new Params()); 
} 

/** 
* Bare bones implementation of ParamMap used in mock. Further tests can expand 
* on this implementation as needed. 
*/ 
class Params implements ParamMap { 
    keys: string[]; 

    private routes: {[key: string]: string|null} = { 
    subject: 'foo', 
    time: 'd-123-1', 
    device: 'all', 
    location: 'c-123' 
    }; 

    constructor() { 
    this.keys = Object.keys(this.routes); 
    } 

    has(name: string): boolean { 
    throw new Error('Method not implemented.'); 
    } 
    get(name: string): string|null { 
    return this.routes[name]; 
    } 
    getAll(name: string): string[] { 
    throw new Error('Method not implemented.'); 
    } 
} 

Und dann in Ihrer Test-Modul stellen Sie sicher, den verspottet Service über die wirklichen ActivatedRoute bieten:

providers: [ 
    { 
    provide: ActivatedRoute, 
    useValue: new MockActivatedRoute(), 
    } 
] 

Zur Vervollständigung, wie ich es in der Komponente I verwenden Ich teste:

ngOnInit() { 
    this.route.paramMap 
     .map((params: ParamMap) => params.get('subject') as string) 
     .subscribe((subject: string) => this.subject = subject); 
} 
9

Managed dies selbst zu lösen, verspotten Sie RouteProvider von

provide(RouteParams, { useValue: new RouteParams({ id: '1' }) })

import { 
    it, 
    inject, 
    injectAsync, 
    describe, 
    beforeEach, 
    beforeEachProviders, 
    TestComponentBuilder 
} from 'angular2/testing'; 

import {Component, provide} from 'angular2/core'; 
import {BaseRequestOptions, Http} from 'angular2/http'; 
import {MockBackend} from 'angular2/http/testing'; 
import {RouteParams, ROUTER_PROVIDERS, ROUTER_PRIMARY_COMPONENT} from 'angular2/router'; 

// Load the implementations that should be tested 
import {Home} from './home'; 
import {Title} from './providers/title'; 

describe('Home',() => { 
    // provide our implementations or mocks to the dependency injector 

    beforeEachProviders(() => [ 
    Title, 
    Home, 
    provide(RouteParams, { useValue: new RouteParams({ id: '1' }) }), 
    BaseRequestOptions, 
    MockBackend, 
    provide(Http, { 
     useFactory: function(backend, defaultOptions) { 
      return new Http(backend, defaultOptions); 
     }, 
     deps: [MockBackend, BaseRequestOptions] 
    }) 
    ]); 

    it('should have a title', inject([ Home ], (home) => { 
    expect(home.title.value).toEqual('Angular 2'); 
    })); 

    it('should have a http', inject([ Home ], (home) => { 
    expect(!!home.http).toEqual(true); 
    })); 

    it('should log ngOnInit', inject([ Home ], (home) => { 
    spyOn(console, 'log'); 
    spyOn(console, 'info'); 
    expect(console.log).not.toHaveBeenCalled(); 
    expect(console.info).not.toHaveBeenCalled(); 

    home.ngOnInit(); 
    expect(console.log).toHaveBeenCalled(); 
    expect(console.info).toHaveBeenCalledWith('1'); 
    })); 

}); 
+0

Danke! Das hat super funktioniert. – Charlie

Verwandte Themen