2017-05-16 14 views
5

Tôi có một vấn đề chế giễu một thành phần với các nhà cung cấp trong góc 4. Đây là mã:Làm thế nào để mô phỏng các thành phần với các nhà cung cấp trong Angular 4? - Đơn vị kiểm tra

import { ComponentFixture, TestBed } from '@angular/core/testing'; 
import { By } from '@angular/core/platform-browser'; 
import { DebugElement } from '@angular/core'; 
import { FormsModule, 
    ReactiveFormsModule, 
    FormBuilder 
} from '@angular/forms'; 
import { Router, RouterModule } from '@angular/router'; 
import { 
    Http, ConnectionBackend, 
    BaseRequestOptions 
} from '@angular/http'; 
import { MockBackend, async } from '@angular/http/testing'; 

import { LoginComponent } from './../../../src/app/login/login.component'; 
import { LoginService } from './../../../src/app/login/login.service'; 
import { LoginComponent } from './../../../src/app/login/login.component'; 
import { LoggerService } from './../../../src/app/logger-service'; 
import { AuthService } from './../../../src/app/pages/auth.service'; 

describe('LoginComponent',() => { 
    let comp: LoginComponent; 
    let fixture: ComponentFixture<LoginComponent>; 
    let de: DebugElement; 
    let el: HTMLElement; 

    beforeEach(() => { 
     // implement mock 
     class loggerService = { 

     }; 

     class loginService = { 

     }; 

     class authService = { 

     }; 

     class router = { 

     }; 

     TestBed.configureTestingModule({ 
      declarations: [ LoginComponent ], 
      imports: [ 
       ReactiveFormsModule, 
       FormsModule 
      ], 
      providers: [ 
       MockBackend, 
       BaseRequestOptions, 
       AuthService, 
       LoginService, 
       LoggerService, 
       RouterModule, 
       { provide: AuthService, useValue: authService }, 
       { provide: LoginService, useClass: LoginService }, 
       { provide: LoggerService, useValue: loggerService }, 
       { 
        provide: Http, useFactory: (backend: ConnectionBackend, 
         defaultOptions: BaseRequestOptions) => { 
         return new Http(backend, defaultOptions); 
        }, deps: [MockBackend, BaseRequestOptions] 
       }, 
       { provide: Router, useClass: router } 
      ] 
     }).compileComponents().then(() => { 
      fixture = TestBed.createComponent(LoginComponent); 

      comp = fixture.componentInstance; 

      comp.detectChanges(); 
      comp.ngOnInit(); 

      loginService = fixture.debugElement.injector.get(LoginService); 
      loggerService = fixture.debugElement.injector.get(LoggerService); 
      authService = fixture.debugElement.injector.get(AuthService); 
      router = fixture.debugElement.injector.get(Router); 
     }); 

    }); 

    it('should create component', async(() => { 
     expect(comp).toBeDefined(); 
    })); 
}); 

Đây là lỗi của tôi:

spec-bundle.js:9 Unhandled Promise rejection: No provider for AuthService! ; Zone: ProxyZone ; Task: Promise.then ; Value: Error {__zone_symbol__error: Error at Error.ZoneAwareError (http://localhost:9876/base/config/spec-bundle.js:9:3748709) a……}

Bất kỳ ý tưởng về những gì tôi đang làm sai ?

Cảm ơn trước :)

Trả lời

4

Vì vậy, một vài điều sẽ xảy ra với tôi. Tôi không chắc chắn nếu họ là vấn đề của bạn mặc dù.

Bạn đang cố gắng phân tích các lớp trống, sử dụng chúng để chèn giả vào thành phần của bạn thay cho dịch vụ thực, và sau đó gán các dịch vụ được tiêm lại cho các biến sơ khai. Thay vào đó, tôi sẽ cố gắng sử dụng các dịch vụ hợp pháp, hoặc đưa chúng ra và nhận một tham chiếu riêng cho chúng.

Trong trường hợp của AuthService, nếu bạn muốn cung cấp dịch vụ thực tế (thậm chí nếu sau này bạn đánh chặn và gián điệp trên các bộ phận của nó), bạn có thể chỉ nói

... 
providers: [AuthService] 
... 

Nếu bạn muốn thử nó, bạn sẽ sử dụng:

class mockAuthService{} 
beforeEach(() => { 
    TestBed.configureTestingModule({ 
    ... 
    providers: [{provide: AuthService, useClass: mockAuthService}] 
    ... 

hoặc

let mockAuthService; 
beforeEach(() => { 
    mockAuthService = {} 
    TestBed.configureTestingModule({ 
    ... 
    providers: [{provide: AuthService, useValue: mockAuthService}] 
    ... 

Ngoài ra, và tôi có thể không kiểm tra lại để xác minh đây là một vấn đề, bạn đã làm điều này tất cả bên trong phạm vi beforeEach, không phải bên ngoài nó (vì vậy sau này bạn có thể tham khảo các biến đó, giả sử bạn muốn). Tôi sẽ di chuyển nó ở trên beforeEach của bạn(), như tôi đã trình bày ở trên/dưới đây.

Đây là ví dụ về ý tôi.

describe('LoginComponent',() => { 
    let comp: LoginComponent; 
    let fixture: ComponentFixture<LoginComponent>; 
    let de: DebugElement; 
    let el: HTMLElement; 


let authServiceReference; 

beforeEach(() => { 
    TestBed.configureTestingModule({ 
     declarations: [ LoginComponent ], 
     imports: [ 
      ReactiveFormsModule, 
      FormsModule 
     ], 
     providers: [ 
      MockBackend, 
      BaseRequestOptions, 
      AuthService, 
      LoginService, 
      LoggerService, 
      RouterModule,     
      { 
       provide: Http, useFactory: (backend: ConnectionBackend, 
        defaultOptions: BaseRequestOptions) => { 
        return new Http(backend, defaultOptions); 
       }, deps: [MockBackend, BaseRequestOptions] 
      }, 
      Router 

     ] 
    }).compileComponents().then(() => { 
     fixture = TestBed.createComponent(LoginComponent); 

     comp = fixture.componentInstance; 

     comp.detectChanges(); 
     comp.ngOnInit(); 


     authServiceReference = Testbed.get(AuthService); // get service you injected above 

    }); 

}); 

it('should create component',() => { 
    expect(comp).toBeDefined(); 
}); // this part really doesn't need to be async. 

Một vài điều bổ sung (Tôi cũng tương đối mới và đây là những thứ tôi đã chọn). Bạn có thể thấy nó ít lộn xộn hơn chỉ đơn giản là lấy một tham chiếu đến các dịch vụ được tiêm tại bản thân bài kiểm tra. Ví dụ:

it('should have a service', inject([SomeService], (serviceHandle: SomeService) => { 
    expect(serviceHandle).toEqual(sameServiceYouTriedToGrabInInitialSetUp); 
} 

Tôi hy vọng điều đó có ý nghĩa lol. Điểm là, dễ dàng hơn nhiều khi chỉ cần lấy nó ở đó. Hơn nữa, bạn có thể tiêm bao nhiêu dịch vụ như bạn muốn nắm tay cầm cho rằng kiểm tra cụ thể.

it('should have a service', inject([SomeService, SomeOtherService, YetOneMoreService], (serviceHandle: SomeService, otherServiceHandle: SomeOtherService, yetAnotherHandle: YetOneMoreService) => { 
     spyOn(serviceHandle, 'isAuthenticated').and.returnsValue(true); 
     spyOn(otherServiceHandle, 'getUrl').and.returnsValue(/home); 
     let yahSpy = spyOn(yetAnotherHandle, 'doSomething'); 
     //code 
      expect (yahSpy.doSomething).toHaveBeenCalled(); 

    } 

Hy vọng điều này sẽ hữu ích.

Các vấn đề liên quan