2016-08-12 6 views
7

Я пытаюсь протестировать компонент, который использует другую услугу. И я хочу изолировать компонент, предоставляя макет услуги. Перед RC5 я могу просто использовать addproviders, который теперь устарел и будет удален следующим RC. Вместо этого я должен использовать TestBed. Когда я предоставляю ложный угловой по какой-то причине, продолжайте искать услуги, от которых зависит макет. И бросает DI exception. Когда я предоставляю все зависимости, которые тестируют, но я не хочу повторять себя для каждого набора тестов. И это нарушает основные принципы OO. Мой тестовый набор:Угловой 2 TestBed с mocks

describe('Component: DummyRestApi',() => { 

    class DummyRestApiTestService { 

    GetAll() { 

     return Rx.Observable.create(observer => { 

     let data:Data[] = []; 

     data.push({ 
      id: 0, 
      data: 'data' 
     }); 

     observer.next(data); 
     observer.complete(); 

     }); 
    } 

    Add(data) { 
    } 
    } 
    let fixture; 
    let myMockWindow:Window; 
    // ToDo use the mocks 
    beforeEach(() => { 
    myMockWindow = <any> {location: <any> {hostname: '127.0.0.1'}}; 
    TestBed.configureTestingModule({ 
     declarations: [DummyRestApiComponent], 
     providers: [ 
     // ServerAddressResolverService, 
     DummyRestApiComponent, 
     // ConfigurationService, 
     {provide: DummyRestApiService, useClass: DummyRestApiTestService}, 
     // {provide: Window, useValue: myMockWindow} 
     ], 
     imports: [FormsModule, HttpModule] 
    }); 
    TestBed.compileComponents().catch(error => console.error(error)); 


    // addProviders([ 
    // DummyRestApiComponent, 
    // {provide: DummyRestApiService, useClass: DummyRestApiTestService}, 
    // ]); 
    }); 


    describe('Initializing',() => { 

    beforeEach(async(() => { 
     console.log('Compiling'); 
     TestBed.compileComponents().catch(error => console.error(error)); 
     console.log('Compiling again'); 
    })); 

    it('should create an instance', async(() => { 
     var fixture = TestBed.createComponent(DummyRestApiComponent); 
     fixture.detectChanges(); 
     expect(fixture.debugElement.componentInstance).toBeTruthy(); 
     } 
    )); 

}); 

Угловая 2.0.0-RC5

+0

Я подтвердил это. Вы должны указать импорт для службы, как будто это не было насмешкой. По крайней мере, в RC5. Однако тест будет использовать макет службы. – Dave

ответ

2

Я только что обновил свой проект семян для RC5 и мой тестовый набор для простого компонента Todo выглядит следующим образом:

import { provide } from '@angular/core'; 
import { TestBed, ComponentFixture, async } from '@angular/core/testing'; 
import { Observable } from 'rxjs/Observable'; 
import 'rxjs/add/observable/of'; 

import { TodoModule } from './todo.module'; 
import { TodoComponent } from './todo.component'; 
import { Todo, TodoService } from './todo.service'; 

class MockTodoService { 
    get todos$(): Observable<Todo[]> { 
     return Observable.of<Todo[]>([ 
      { task: 'Task 1', description: 'Description 1', completed: false }, 
      { task: 'Task 2', description: 'Description 2', completed: false } 
     ]); 
    } 

    loadAll() { } 

    add(newTodo: Todo) { } 
} 

describe('TodoComponent',() => { 

    beforeEach(() => { 
     this.service = new MockTodoService(); 

     TestBed.configureTestingModule({ 
      imports: [TodoModule], 
      providers: [provide(TodoService, { useValue: this.service })] 
     }); 

     this.fixture = TestBed.createComponent(TodoComponent); 
    }); 

    it('should print out todo tasks', async(() => { 
     this.fixture.whenStable().then(() => { 
      let element = this.fixture.nativeElement; 
      this.fixture.detectChanges(); 

      expect(element.querySelectorAll('li').length).toBe(2); 
     }); 
    })); 

    it('should call the service on init', async(() => { 
     this.fixture.whenStable().then(() => { 
      spyOn(this.service, 'loadAll'); 
      this.fixture.detectChanges(); 

      expect(this.service.loadAll).toHaveBeenCalled(); 
     }); 
    })); 
}); 

Сам проект семян можно найти по адресу: https://github.com/froko/ng2-seed-webpack

Надеюсь, это поможет.

+2

Но [журнал изменений RC5] (https://github.com/angular/angular/blob/master/CHANGELOG.md#breaking-changes-1) также указывает, что «ngModel» теперь всегда асинхронно при обновлении. что в тестах вместо вызова 'ComponentFixture.detectChanges' вам нужно использовать' ComponentFixture.whenStable', который является асинхронным. " Вы уже используете 'whenStable', но вы также используете' detectChanges'. Возможно ли, что ваш тест будет работать, если вы сейчас просто удалите 'this.fixture.detectChanges()'? –

5

Обратите внимание, что ответ Patrick Ineichens использует предоставление, которое устарело.

providers: [provide(TodoService, { useValue: this.service })] 

вместо этого следует прочитать:

providers: [{provide:TodoService, useValue: this.service }] 
Смежные вопросы