2016-10-18 2 views
4

Я перешел от RC4 к финальной версии (2.1.0), и я реорганизую свои модульные тесты, чтобы они соответствовали синтаксису 2.1.0. Это легко, за исключением HTTP-издевательств.Как написать тестовый модульный модуль HTTP в окончательной версии Angular 2?

Я не могу найти примеры того, как издеваться HTTP запросов в 2.1.0

Вот тестовый модуль RC4 HTTP. Как мне переписать это в финальной версии 2.1.0?

it('ngOnInit()', 
    async(inject([TestComponentBuilder, XHRBackend], (tcb:TestComponentBuilder, mockBackend:MockBackend) => { 
    tcb.createAsync(Route1ListComponent).then((fix:ComponentFixture<Route1ListComponent>) => { 

    // THIS BLOCK OF CODE I NEED HELP TO RE-WRITE TO 2.1.0 
    mockBackend.connections.subscribe(
     (connection:MockConnection) => { 
     connection.mockRespond(new Response(
      new ResponseOptions({ 
       body: persons 
      } 
     ))); 
     }); 

    // THIS BLOCK OF CODE WILL NOT CHANGE 
    let instance = fix.componentInstance; 
    instance.ngOnInit(); 
    expect(instance.persons.length).toBe(3); 
    }); 
}))); 

ПРИМЕЧАНИЕ: НЕ ПРЕДОСТАВЛЯЙТЕ RC-код, пожалуйста. Спасибо

ответ

4

Первое, что вам нужно сделать, это настроить TestBed. Больше нет TestComponentBuilder. С TestBed это похоже на настройку @NgModule с нуля, только для тестовой среды. Это означает, что вы добавите тестируемый компонент в declarations, добавьте всех провайдеров в provider, а любой импорт - в imports.

Чтобы настроить фиктивный сервер для провайдера Http, вы должны просто создать Http от MockBackend.

beforeEach(() => { 
    TestBed.configureTestingModule({ 
    imports: [ HttpModule ], 
    declarations: [ RouteListComponent ], 
    providers: [ 
     MockBackend, 
     BaseRequestOptions, 
     { 
     provide: Http, 
     useFactory: (backend: MockBackend, options: BaseRequestOptions) => { 
      return new Http(backend, options); 
     }, 
     deps: [ MockBackend, BaseRequestOptions ] 
     } 
    ] 
    }) 
}) 

Это должно быть для конфигурации, если вы не нуждаетесь ни в каких других провайдерах или импорте, о которых я не знаю.

Для теста сначала нужно сделать тест async, так как вы будете выполнять асинхронные операции в тесте. Это не изменилось с RC, вы просто используете async. Если компонент использует templateUrl (и вы не используете Webpack), тогда вам нужно будет позвонить TestBed.compileComponents(), в противном случае нет необходимости. После этого вы можете создать компонент с TestBed.createComponent

let fixture: ComponentFixture<RouteListComponent>; 
let component: RouteListComponent; 

beforeEach(async(() => { 
    TestBed.configureTestingModule({ ... }) 
    .compileComponents().then(() => { 
    fixture = TestBed.createComponent(RouteListComponent); 
    component = fixture.componentInstance; 
    fixture.detectChanges(); 
    }); 
})); 

it('...', async(inject([MockBackend], (backend: MockBackend) => { 

}))) 

Практически все вещи, связанные с выше тестирования могут быть импортированы из @angular/core/testing. Ваше использование MockBackend все равно будет таким же.

Другое примечание, вам не нужно называть component.ngOnInit. Это называется рамкой, когда вы звоните fixture.detectChanges()

Смотрите также:

  • Testing documentation для более полного обследования поддержки тестирования.
+0

Большое спасибо за этот ответ, без этого я не мог бы достичь своего решения, изложенного здесь. Мое решение основано на этом, но, правильно или неправильно, избегает использования .. async (inject ([MockBackend], (backend: MockBackend) .. этот ответ был высоко оценен ... большое спасибо еще раз :) ... if у вас есть какая-либо обратная связь по моему окончательному решению, это было бы очень полезно ... +1 – danday74

2

Большое спасибо @peeskillet помог мне достичь мой ответ ..

import {APP_BASE_HREF} from '@angular/common'; 
import {async, ComponentFixture, TestBed} from '@angular/core/testing'; 
import {By} from '@angular/platform-browser'; 
import {AppModule} from '../../../app.module'; 
import {persons} from '../../../data/persons'; 
import {Route1ListComponent} from './route1-list.component'; 

// HTTP mocking imports 
import {BaseRequestOptions, Http, Response, ResponseOptions} from '@angular/http'; 
import {MockBackend, MockConnection} from '@angular/http/testing'; 

describe('route1-list.component.ts',() => { 

    let fix: ComponentFixture<Route1ListComponent>; 
    let instance: Route1ListComponent; 
    let injector: any; 

    beforeEach(async(() => { 
    TestBed.configureTestingModule({ 
     imports: [AppModule], 
     providers: [{provide: APP_BASE_HREF, useValue: '/'}, 
     MockBackend, 
     BaseRequestOptions, 
     { 
      provide: Http, 
      useFactory: (pBackend: MockBackend, pOptions: BaseRequestOptions) => { 
      return new Http(pBackend, pOptions); 
      }, 
      deps: [MockBackend, BaseRequestOptions] 
     }] 
    }).compileComponents() 
     .then(() => { 
     fix = TestBed.createComponent(Route1ListComponent); 
     instance = fix.componentInstance; 
     injector = fix.debugElement.injector; 
     }); 
    })); 

    it('should instantiate component',() => { 
    expect(instance).toEqual(jasmine.any(Route1ListComponent)); 
    }); 

    it('should have expected text',() => { 
    let el = fix.debugElement.query(By.css('section.route1-list')).nativeElement; 
    expect(el.textContent).toMatch(/route 1 list view/i, 'should have expected text'); 
    }); 

    it('ngOnInit()', async(() => { 
    let backend = injector.get(MockBackend); 
    backend.connections.subscribe(
     (connection: MockConnection) => { 
     connection.mockRespond(new Response(
      new ResponseOptions({ 
       body: persons 
      } 
     ))); 
     }); 

    fix.detectChanges(); // Calls instance.ngOnInit() 
    expect(instance.persons.length).toBe(3); 
    })); 

    it('ngOnInit() failure', async(() => { 
    let backend = injector.get(MockBackend); 
    backend.connections.subscribe(
     (connection: MockConnection) => { 
     connection.mockError(new Error('error')); 
     }); 

    fix.detectChanges(); // Calls instance.ngOnInit() 
    expect(instance.persons).toBeUndefined(); 
    })); 

}); 

Обратите внимание, что на момент написания Документах Angular2 в ..

https://angular.io/docs/ts/latest/api/http/testing/index/MockBackend-class.html

https://angular.io/docs/ts/latest/api/http/testing/index/MockConnection-class.html

представляется неправильным.

Когда я использую Injector.resolveAndCreate, как указано в документации, я получаю ошибку:

Property 'resolveAndCreate' does not exist on type 'typeof Injector'.

Чтобы исправить это я должен основывать свой ответ на ответ, предоставленной @peeskillet

+0

Полный рабочий код на https://github.com/danday74/angular2-coverage/tree/master – danday74