2017-02-12 6 views
3

Я работаю через Угловое 2 примера тестирования здесь https://angular.io/docs/ts/latest/guide/testing.htmlУгловая 2-я единица измерения тестовой службы не изменяется?

Добро пожаловать компонент

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.'; 
    } 
} 

Тест спецификации

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"'); 
    }); 

}); 

Последние 2 его() тесты не удалось, потому что значения заглушек услуг не изменение после

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

и

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

Любая идея, почему угловой тестовый модуль не удалось обнаружить изменение?

Uodate

Я нашел его. fixture.detectChanges() триггеры ngOnInit(). fixture.detectChanges() в beforeEach() является виновником. Поскольку он инициализировал компонент, fixture.detectChanges() в it() не будет инициализировать компонент снова. Таким образом, удалив fixture.detectChanges() от beforeEach(), fixture.detectChanges() в it() получит шанс вызвать ngOnInit() и все тесты пройдут.

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

Спасибо, у меня была та же проблема в том же кусочке кода. Не знаю, почему у меня была эта строка в 'beforeEach()'. Было бы неплохо, если бы это было объяснено на [странице тестирования] (https://angular.io/guide/testing#automatic-change-detection) – redOctober13

+0

Кажется, что это также проблема, если вы используете 'ComponentFixtureAutoDetect' в настройке и 'fixture.detectChanges()' в тесте. – redOctober13

ответ

1

Попробуйте initilize ваш сервис в ваш "это"

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

Yoav, я нашел проблему и обновил свой пост. Я все же поддержал вас за ваш ответ, потому что это помогло мне очистить мои мысли. – Shawn

+0

Вы можете разместить свое решение? –

+0

Несомненно. Просто опубликовано. – Shawn

0

Вот решение.

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"'); 
    }); 

});