我尝试为使用服务的角度组件编写测试。 我用true初始化了我的userServiceStub属性isLoggedIn,但是当我运行测试组件时,UserService属性为false。 我尝试删除Injectable()装饰器并将匿名对象更改为UserService。
测试
import { async, ComponentFixture, ComponentFixtureAutoDetect, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
import { WelcomeComponent } from './welcome.component';
import { UserService, User } from './model';
class UserServiceMock{
isLoggedIn: boolean = true;
user: User = {name: 'Mock user'};
}
describe('Welcome component tests', () =>{
let component: WelcomeComponent;
let fixture: ComponentFixture<WelcomeComponent>;
let debugElment: DebugElement;
let htmlElement: HTMLElement;
let userService: UserService;
let userServiceStub: {
isLoggedIn: boolean;
user: { name: string }
};
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [WelcomeComponent],
})
.overrideComponent(WelcomeComponent, {
set: {
providers: [
{provide: UserService, useClass: UserServiceMock}
]
}
})
.compileComponents()
.then(() =>{
fixture = TestBed.createComponent(WelcomeComponent);
component = fixture.componentInstance;
userService = TestBed.get(UserService);
console.log(userService);
debugElment = fixture.debugElement.query(By.css('.welcome'));
htmlElement = debugElment.nativeElement;
});
});
it('stub object and injected UserService should not be the same', () =>{
expect(userServiceStub === userService).toBe(false);
});
it('changing the stub object has no effect on the injected service', () =>{
userServiceStub.isLoggedIn = false;
expect(userService.isLoggedIn).toBe(true);
});
it('should welcome user', () => {
fixture.detectChanges();
const content = htmlElement.textContent;
expect(content).toContain('Welcome');
})
})
欢迎组件
import { Component, OnInit } from '@angular/core';
import { UserService } from './model';
@Component({
selector: 'app-welcome',
template: '<h3 class="welcome" ><i>{{welcome}}</i></h3>',
providers: [UserService]
})
export class WelcomeComponent implements OnInit {
welcome: string = '-- not initialized yet --';
constructor(private userService: UserService) { }
ngOnInit(): void {
this.welcome = this.userService.isLoggedIn ?
'Welcome, ' + this.userService.user.name :
'Please log in.';
}
}
用户服务
import { Injectable } from '@angular/core';
@Injectable()
export class UserService {
isLoggedIn: boolean;
user: User;
}
export class User{
name: string;
}
测试结果失败 link
我的问题是:如何正确注入服务?
答案 0 :(得分:1)
1)如果使用compileComponent(),则必须使用async
或fakeAsync
:
2)当您在组件内提供服务时,您应该使用:
fixture.debugElement.injector.get(UserService);
获得注入服务
3)您无法更改未定义对象的属性:
let userServiceStub: {
isLoggedIn: boolean;
user: { name: string }
};
userServiceStub.isLoggedIn = false;
userServiceStub
未定义。我不明白为什么userServicesSub在这里,如果您不将其用作useValue,如此处所述https://angular.io/docs/ts/latest/guide/testing.html#!#final-setup-and-tests
所以你的测试看起来像:
describe('Welcome component tests', () =>{
let component: WelcomeComponent;
let fixture: ComponentFixture<WelcomeComponent>;
let debugElment: DebugElement;
let htmlElement: HTMLElement;
let userService: UserService;
let userServiceStub: {
isLoggedIn: boolean;
user: { name: string }
} = {
isLoggedIn: true,
user: { name: 'Stub user'}
};
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [WelcomeComponent],
})
.overrideComponent(WelcomeComponent, {
set: {
providers: [
{provide: UserService, useClass: UserServiceMock}
]
}
})
.compileComponents()
.then(() =>{
fixture = TestBed.createComponent(WelcomeComponent);
component = fixture.componentInstance;
//userService = TestBed.get(UserService);
userService = fixture.debugElement.injector.get(UserService);
console.log(userService);
debugElment = fixture.debugElement.query(By.css('.welcome'));
htmlElement = debugElment.nativeElement;
});
}));
it('stub object and injected UserService should not be the same', () =>{
expect(userServiceStub === userService).toBe(false);
});
it('changing the stub object has no effect on the injected service', () =>{
userServiceStub.isLoggedIn = false;
expect(userService.isLoggedIn).toBe(true);
});
it('should welcome user', () => {
fixture.detectChanges();
const content = htmlElement.textContent;
expect(content).toContain('Welcome');
})
})
<强> Live Example 强>