9

我在为Angular2组件测试中注入RouteParams依赖项的模拟器时遇到了一些麻烦。我的一般想法是,我可能会错过一些供应商。Angular2 - 在测试中嘲弄RouteParams

测试失败:

 
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. 

有谁知道这个问题可能是什么?

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

}); 

回答

1

对于谁在这里,即使它们与Angular4

工作,我只是一往直前,创造了陆地上的人嘲笑RouteProvider一个模拟。我想诀窍是嘲笑你需要的ActivatedRoute的部分。对于我这个做的:

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

,然后确保在您的测试模块,用户提供了真正的ActivatedRoute嘲笑的服务:

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

完成,我用它在Component我的方式'm testing:

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

设法解决这个自己,你用

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

谢谢!这很好。 – Charlie