2017-02-22 45 views
0

У меня вопрос о тестировании маршрутизируемого компонента в угловом2.Тестирование компонента, который зависит от маршрута param

Вот простой компонент, который зависит от маршрута с параметром 'foo'. Атрибут foo в компоненте будет установлен на значение параметра.

import {Component, OnInit} from '@angular/core'; 
import {ActivatedRoute, Params} from '@angular/router'; 

@Component({ 
    selector: 'my-component', 
    templateUrl: './my-component.html' 
}) 
export class MyComponent implements OnInit 
{ 
    foo: string; 

    constructor(
     private route: ActivatedRoute 
    ) 
    { 
    } 

    ngOnInit() 
    { 
     this.route.params.subscribe((params: Params) => { 
      this.foo = params['foo']; 
     }); 
    } 
} 

Теперь я хочу проверить, что если компонент будет создан с помощью маршрута, параметр будет установлен правильно. Поэтому где-то я хочу иметь expect(component.foo).toBe('3');.

import {TestBed, ComponentFixture, async} from '@angular/core/testing'; 
import {DebugElement} from '@angular/core'; 
import {By} from '@angular/platform-browser'; 
import {Params, ActivatedRoute} from '@angular/router'; 

import {Observable} from 'rxjs'; 

import {MyComponent} from './MyComponent'; 

describe('MyComponent',() => { 
    let mockParams, mockActivatedRoute; 

    let component: MyComponent; 
    let fixture: ComponentFixture<MyComponent>; 
    let debugElement: DebugElement; 
    let element: HTMLElement; 

    beforeEach(async(() => { 
     mockParams = Observable.of<Params>({foo: '3'}); 
     mockActivatedRoute = {params: mockParams}; 

     TestBed.configureTestingModule({ 
      declarations: [ 
       MyComponent 
      ], 
      providers: [ 
       {provide: ActivatedRoute, useValue: mockActivatedRoute} 
      ] 
     }).compileComponents(); 
    })); 

    beforeEach(() => { 
     fixture = TestBed.createComponent(MyComponent); 
     component = fixture.componentInstance; 

     debugElement = fixture.debugElement; 
     element = debugElement.nativeElement; 

     fixture.detectChanges(); 
    }); 

    it('should set foo to "3"',() => { 
     expect(component.foo).toBe('3'); 
    }); 
}); 

Моя проблема заключается в том, что я не знаю, как ждать, пока разрешения маршрута не закончена, и я могу сделать expect(). И в этом примере тест терпит неудачу, и в нем говорится: «Ожидаемое неопределенное значение« 3 ».».

Может ли кто-нибудь мне помочь?

Спасибо!

ответ

1

Хорошо, прочитав немного в документации на угловую2, я увидел их класс ActivatedRouteStub. Я создал этот класс заглушки и заменил мой оригинальный макет этим новым классом. Теперь он работает (узнайте строку mockActivatedRoute.testParams = {foo: '3'}; во втором перед каждым).

import {TestBed, ComponentFixture, async} from '@angular/core/testing'; 
import {DebugElement} from '@angular/core'; 
import {By} from '@angular/platform-browser'; 
import {Params, ActivatedRoute} from '@angular/router'; 

import {Observable} from 'rxjs'; 

import {MyComponent} from './MyComponent'; 

import { BehaviorSubject } from 'rxjs/BehaviorSubject'; 

@Injectable() 
export class ActivatedRouteStub 
{ 
    private subject = new BehaviorSubject(this.testParams); 
    params = this.subject.asObservable(); 

    private _testParams: {}; 
    get testParams() { return this._testParams; } 
    set testParams(params: {}) { 
     this._testParams = params; 
     this.subject.next(params); 
    } 
} 

describe('MyComponent',() => { 
    let mockParams, mockActivatedRoute; 

    let component: MyComponent; 
    let fixture: ComponentFixture<MyComponent>; 
    let debugElement: DebugElement; 
    let element: HTMLElement; 

    beforeEach(async(() => { 
     mockActivatedRoute = new ActivatedRouteStub(); 

     TestBed.configureTestingModule({ 
      declarations: [ 
       MyComponent 
      ], 
      providers: [ 
       {provide: ActivatedRoute, useValue: mockActivatedRoute} 
      ] 
     }).compileComponents(); 
    })); 

    beforeEach(() => { 
     fixture = TestBed.createComponent(MyComponent); 
     component = fixture.componentInstance; 

     debugElement = fixture.debugElement; 
     element = debugElement.nativeElement; 

     mockActivatedRoute.testParams = {foo: '3'}; 

     fixture.detectChanges(); 
    }); 

    it('should set foo to "3"',() => { 
     expect(component.foo).toBe('3'); 
    }); 
}); 

Как вы думаете, это правильный путь?

+0

Ваш тест, который проверяет данные компонента, устанавливается в соответствии с параметром route, выглядит хорошо для меня. Тест основан только на макетной реализации ActivatedRoute, а не на реальной. Это хорошо. Единичные тесты должны быть как можно более изолированными. Цель такого теста - идентифицировать проблемы только в одном компоненте, а не взаимодействовать с другими компонентами или службами или с угловыми классами или с браузером. Если вы представили другие подобные ненужные взаимодействия, это повлечет за собой результаты тестирования, потому что эти другие вещи могут маскировать проблемы внутри вашего компонента. – Will

 Смежные вопросы

  • Нет связанных вопросов^_^