2017-02-12 7 views
3

Ich arbeite durch Angular 2 Testbeispiele hier https://angular.io/docs/ts/latest/guide/testing.htmlAngular 2 Unit Test Service Stub Wert ändert sich nicht?

Willkommen Komponente

import { Component, OnInit } from '@angular/core'; 
import { UserService }  from './user.service'; 

@Component({ 
    selector: 'app-welcome', 
    template: '<h3 class="welcome" ><i>{{welcome}}</i></h3>' 
}) 
export class WelcomeComponent implements OnInit { 
    welcome = '-- not initialized yet --'; 
    constructor(private userService: UserService) {  
    } 

    ngOnInit(): void { 
    this.welcome = this.userService.isLoggedIn ? 
     'Welcome, ' + this.userService.user.name : 
     'Please log in.'; 
    } 
} 

Test-spec

import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 
import { By } from '@angular/platform-browser'; 
import { DebugElement } from '@angular/core'; 
import { WelcomeComponent } from './welcome.component'; 
import { UserService } from './user.service'; 

describe('WelcomeComponent',() => { 
    let component: WelcomeComponent; 
    let fixture: ComponentFixture<WelcomeComponent>; 
    let de:  DebugElement; 
    let el:  HTMLElement; 
    let userServiceStub: UserService; 
    let userService:UserService; 

    beforeEach(async(() => { 
    // Declare stub UserService for test purposes 
    let userServiceStub = { 
     isLoggedIn: true, 
     user: { name: 'Test User'} 
    }; 

    TestBed.configureTestingModule({ 
     declarations: [ WelcomeComponent ], 
     providers: [ {provide: UserService, useValue: userServiceStub } ] 
    }) 
    .compileComponents(); 
    })); 

    beforeEach(() => { 
    fixture = TestBed.createComponent(WelcomeComponent); 
    component = fixture.componentInstance; 
    //userService = TestBed.get(UserService); 
    userService = fixture.debugElement.injector.get(UserService); 

    // get the "welcome" element by CSS selector (e.g., by class name) 
    de = fixture.debugElement.query(By.css('.welcome')); 
    el = de.nativeElement; 
    fixture.detectChanges(); 
    }); 

    it('should create',() => { 
    expect(component).toBeTruthy(); 
    }); 

    it('should welcome the user',() => { 
    fixture.detectChanges(); 
    const content = el.textContent; 
    expect(content).toContain('Welcome', '"Welcome ..."'); 
    expect(content).toContain('Test User', 'expected name'); 
    }); 

    it('should welcome "Bubba"',() => { 
    userService.user.name = 'Bubba'; 
    fixture.detectChanges(); 
    expect(el.textContent).toContain('Bubba'); 
    }); 

    it('should request login if not logged in',() => { 
    userService.isLoggedIn = false; 
    fixture.detectChanges(); 
    const content = el.textContent; 
    expect(content).not.toContain('Welcome', 'not welcomed'); 
    expect(content).toMatch(/log in/i, '"log in"'); 
    }); 

}); 

Die letzten 2 it() Tests nicht bestanden, weil die Service-Stub Werte nicht tat Änderung nach

userService.user.name = 'Bubba'; 
fixture.detectChanges(); 

und

userService.isLoggedIn = false; 
fixture.detectChanges(); 

Irgendeine Idee, warum angular Testmodul Änderung nicht feststellen konnte?

Uodate

ich es gefunden. fixture.detectChanges() löst ngOnInit() aus. fixture.detectChanges() in beforeEach() ist der Schuldige. Da die Komponente initialisiert wurde, initialisiert die fixture.detectChanges() in it() die Komponente nicht erneut. So durch Entfernen fixture.detectChanges() von beforeEach() die fixture.detectChanges() in it() wird die Chance haben, ngOnInit() auslösen und alle Tests durchlaufen.

beforeEach(() => { 
    fixture = TestBed.createComponent(WelcomeComponent); 
    component = fixture.componentInstance; 
    //userService = TestBed.get(UserService); 
    userService = fixture.debugElement.injector.get(UserService); 

    // get the "welcome" element by CSS selector (e.g., by class name) 
    de = fixture.debugElement.query(By.css('.welcome')); 
    el = de.nativeElement; 
    // fixture.detectChanges(); // this is the culprit. 
    }); 
+0

Dank, hatte ich das gleiche Problem in dem gleichen Stück Code. Ich weiß nicht, warum ich diese Zeile in 'beforeEach()' hatte. Es wäre schön, wenn das auf der [Testseite] erklärt würde (https://angular.io/guide/testing#automatic-change-detection) – redOctober13

+0

Es scheint auch ein Problem zu sein, wenn Sie 'ComponentFixtureAutoDetect' im Setup verwenden und 'fixture.detectChanges()' im Test. – redOctober13

Antwort

1

Versuchen Sie, Ihre Leistung nach "es"

it('should welcome "Bubba"' , inject([UserService], (userService: UserService) => { 
    userService.user.name = 'Bubba'; 
    fixture.detectChanges(); 
    expect(el.textContent).toContain('Bubba'); 
    })); 
+0

Yoav, ich habe das Problem gefunden und meinen Beitrag aktualisiert. Ich habe dich immer noch für deine Antwort aufgestuft, weil es mir geholfen hat, meine Gedanken zu klären. – Shawn

+0

können Sie Ihre Lösung posten? –

+0

Sicher. Gerade gepostet. – Shawn

0

Hier ist die Lösung initilize.

welcome.component.spec.ts

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

import { WelcomeComponent } from './welcome.component'; 
import { UserService } from './user.service'; 
describe('WelcomeComponent',() => { 
    let component: WelcomeComponent; 
    let fixture: ComponentFixture<WelcomeComponent>; 
    let de:  DebugElement; 
    let el:  HTMLElement; 
    let userServiceStub: UserService; 
    let userService:UserService; 

    beforeEach(async(() => { 
    // Declare stub UserService for test purposes 
    let userServiceStub = { 
     isLoggedIn: true, 
     user: { name: 'Test User'} 
    }; 

    TestBed.configureTestingModule({ 
     declarations: [ WelcomeComponent ], 
     providers: [ {provide: UserService, useValue: userServiceStub } ] 
    }) 
    .compileComponents(); 
    })); 

    beforeEach(() => { 
    fixture = TestBed.createComponent(WelcomeComponent); 
    component = fixture.componentInstance; 
    // UserService from the root injector 
    //userService = TestBed.get(UserService); 
    userService = fixture.debugElement.injector.get(UserService); 

    // get the "welcome" element by CSS selector (e.g., by class name) 
    de = fixture.debugElement.query(By.css('.welcome')); 
    el = de.nativeElement; 
    }); 

    it('should create',() => { 
    expect(component).toBeTruthy(); 
    }); 

    it('should welcome the user',() => { 
    fixture.detectChanges(); 
    const content = el.textContent; 
    expect(content).toContain('Welcome', '"Welcome ..."'); 
    expect(content).toContain('Test User', 'expected name'); 
    }); 

    it('should welcome "Bubba"', () => { 
    userService.user.name = 'Bubba'; 
    fixture.detectChanges(); 
    expect(el.textContent).toContain('Bubba'); 
    }); 

    it('should request login if not logged in',() => { 
    userService.isLoggedIn = false; 
    fixture.detectChanges(); 
    const content = el.textContent; 
    expect(content).not.toContain('Welcome', 'not welcomed'); 
    expect(content).toMatch(/log in/i, '"log in"'); 
    }); 

}); 
Verwandte Themen