Tôi đang cố gắng thử nghiệm thành phần Angular 2 sử dụng dịch vụ. Các dịch vụ đã Http tiêm vào nó, mà tôi không quan tâm đến thử nghiệm vì vậy tôi đang cố gắng để thử các dịch vụ và gián điệp về cuộc gọi phương thức của dịch vụ. Đây là một cái gì đó tôi đã khá quen thuộc với làm trong Angular 1 nhưng tôi chỉ không thể làm việc trong Angular 2. Lỗi tôi nhận được là Không có nhà cung cấp cho Http! Tôi quan tâm đến việc theo dõi các phương pháp dịch vụ thực tế hơn là chế nhạo nó.Kiểm tra thành phần góc 2 với gián điệp Jasmine "Không có nhà cung cấp cho Http!" lỗi
thành phần của tôi trông như thế này:
import { Component, OnInit } from '@angular/core';
import { NavBarLink } from '../../models/nav-bar-link';
import { NavBarService } from '../../services/nav-bar/nav-bar.service';
@Component({
selector: 'nav-bar',
providers: [NavBarService],
moduleId: module.id,
templateUrl: 'nav-bar.template.html'
})
export class NavBarComponent {
constructor(private _navBarService: NavBarService) { }
links: NavBarLink[];
getLinks(): void {
this._navBarService.getNavBarLinks().then(data => this.links = data);
}
ngOnInit(): void {
this.getLinks();
}
}
Và dịch vụ của tôi trông như thế này:
import { Injectable } from '@angular/core';
import { Headers, Http } from '@angular/http';
import 'rxjs/add/operator/toPromise';
import { Urls } from '../../constants/urls.constants';
import { NavBarLink } from '../../models/nav-bar-link';
@Injectable()
export class NavBarService {
constructor(private _http: Http,
private _urls: Urls) { }
getNavBarLinks():Promise<NavBarLink[]> {
return this._http.get(this._urls.NAV_BAR_LINKS)
.toPromise()
.then(response => {
let navLinks = [];
for(let navLink of response.json()) {
navLinks.push(new NavBarLink(navLink.id, navLink.description, navLink.route));
}
return navLinks;
})
.catch(this.handleError);
}
private handleError(error: any): Promise<any> {
console.error('An error occurred', error); // for demo purposes only
return Promise.reject(error.message || error);
}
}
Và cuối cùng thử nghiệm của tôi trông như thế này
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { Provider } from '@angular/core';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
import { NavBarComponent } from './nav-bar.component';
import { NavBarService } from '../../services/nav-bar/nav-bar.service';
import { Observable } from 'rxjs/Rx';
let comp: NavBarComponent;
let fixture: ComponentFixture<NavBarComponent>;
let navBarService;
class MockNavBarService extends NavBarService{
constructor() {
super(null, null);
}
}
describe ('NavBarComponent tests',() => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ NavBarComponent ],
providers: [ {provide: NavBarService, useClass: MockNavBarService} ]
})
.compileComponents()
.then(createComponent);
}));
it('should call the getNavBarLinks when ngOnInit is called',() => {
comp.ngOnInit();
expect(navBarService.getNavBarLinks).toHaveBeenCalled();
});
});
function createComponent() {
fixture = TestBed.createComponent(NavBarComponent);
comp = fixture.componentInstance;
navBarService = fixture.debugElement.injector.get(NavBarService);
spyOn(navBarService, 'getNavBarLinks').and.returnValue(Promise.resolve([]));
}
Vấn đề với giải pháp này là bạn đang mang trong module mà phụ thuộc của dịch vụ mà thành phần của bạn tiêu thụ mà tăng thêm độ phức tạp cho thử nghiệm thành phần của bạn. Bất kỳ lúc nào NavBarService thay đổi các nhà cung cấp của nó, bạn phải cập nhật mọi tệp kiểm tra tiêu thụ hoặc dựa vào NavBarComponent. Bằng cách chế nhạo dịch vụ với một lớp không mở rộng dịch vụ ban đầu, bạn cắt sự phức tạp phụ thuộc đó ra khỏi thư mục gốc của nó. Điều này sẽ làm cho các bài kiểm tra của bạn sạch hơn và ít dễ bị chú ý hơn nếu bạn thay đổi dịch vụ. – pe8ter