具有可观察性的 Karma Jasmine,代码覆盖率未完全覆盖
Karma Jasmine with observable, code coverage not fully coveraged
我尝试为 ngOnInit 做一些单元测试,我使用 jasmine/karma 作为单元测试套件。我有一个看起来像这个组件的组件:
hasQuestionTree: boolean;
constructor(
private breakpointObserver: BreakpointObserver,
private authService: AuthService,
private sidebarService: SidebarService
) {}
ngOnInit() {
this.loginStatusSubscription = this.authService
.loginStatus()
.subscribe(user => {
this.isLoggedIn = this.authService.isLoggedIn(user);
});
this.hasQuestionTree = this.sidebarService.sidebar;
this.sidebarService
.hasSidebar()
.subscribe(hasSidebar => (this.hasQuestionTree = hasSidebar));
}
边栏服务如下所示:
xport class SidebarService {
private _sidebar = false;
public sidebarObservable: Observable<boolean>;
public sidebarSubject = new ReplaySubject<boolean>(1);
constructor() {
this.sidebarObservable = this.sidebarSubject.asObservable();
}
public get sidebar(): boolean {
return this._sidebar;
}
public hasSidebar(): Observable<boolean> {
// this.sidebarSubject.next(this.sidebar);
return this.sidebarObservable;
}
public setSidebar(has: boolean) {
this._sidebar = has;
this.sidebarSubject.next(has);
}
我有这样的单元测试:
describe('MainNavComponent', () => {
let component: MainNavComponent;
let fixture: ComponentFixture<MainNavComponent>;
const fakeSidebar = {
sidebarState: of({ sidebar: false }),
};
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [NoopAnimationsModule, AppModule],
providers: [{ provide: AuthService, useClass: AuthMockService },
{ provide: SidebarService, useValue: fakeSidebar }]
})
.compileComponents()
.then(() => {
fixture = TestBed.createComponent(MainNavComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
}));
it('should compile', () => {
expect(component).toBeTruthy();
});
it('should isLoggedIn to true', () => {
//Act
component.login();
// Assert
expect(component.isLoggedIn).toBeTruthy();
});
it('should isLoggedOut to true', () => {
//Act
component.logout();
//Assert
expect(component.isLoggedIn).toBeFalsy();
expect(component.logout).toBeTruthy();
});
it('Should show the sidebar when hasQuestionTree is true', () => {
expect(component.hasQuestionTree).toEqual(false);
});
});
但是这部分:
hasSidebar => (this.hasQuestionTree = hasSidebar));
在代码覆盖率中仍然是红色。
所以我的问题是,如何以正确的方式测试该部分?
谢谢。
好的,我现在是这样的:
const fakeSidebar = {
hasSidebar: () => of({ sidebar: false }),
};
还有这个:
it('Should show the sidebar when hasQuestionTree is true', () => {
expect(component.hasQuestionTree).toEqual(true);
});
但是我得到这个错误:
MainNavComponent Should show the sidebar when hasQuestionTree is true
Expected Object({ sidebar: false }) to equal true.
可能是我遗漏了一些东西,但你在 this.sidebarService
上调用 hasSidebar()
,它随 fakeSidebar
一起提供,但这个对象实际上没有定义 [=14] =] 方法?对我来说,你的模拟对象看起来应该是这样的:
const fakeSidebar = {
hasSidebar: () => of(true),
};
使用 of
运算符也会导致同步可观察对象,因此不需要任何 async
助手,但您可能想使用 observeOn
运算符来更改它并传递 asyncScheduler
来模拟真实世界的行为?!
也更新了这个答案,但我实际上不明白你测试的目的。您只是在测试模拟方法是否 returns 指定的值??
我尝试为 ngOnInit 做一些单元测试,我使用 jasmine/karma 作为单元测试套件。我有一个看起来像这个组件的组件:
hasQuestionTree: boolean;
constructor(
private breakpointObserver: BreakpointObserver,
private authService: AuthService,
private sidebarService: SidebarService
) {}
ngOnInit() {
this.loginStatusSubscription = this.authService
.loginStatus()
.subscribe(user => {
this.isLoggedIn = this.authService.isLoggedIn(user);
});
this.hasQuestionTree = this.sidebarService.sidebar;
this.sidebarService
.hasSidebar()
.subscribe(hasSidebar => (this.hasQuestionTree = hasSidebar));
}
边栏服务如下所示:
xport class SidebarService {
private _sidebar = false;
public sidebarObservable: Observable<boolean>;
public sidebarSubject = new ReplaySubject<boolean>(1);
constructor() {
this.sidebarObservable = this.sidebarSubject.asObservable();
}
public get sidebar(): boolean {
return this._sidebar;
}
public hasSidebar(): Observable<boolean> {
// this.sidebarSubject.next(this.sidebar);
return this.sidebarObservable;
}
public setSidebar(has: boolean) {
this._sidebar = has;
this.sidebarSubject.next(has);
}
我有这样的单元测试:
describe('MainNavComponent', () => {
let component: MainNavComponent;
let fixture: ComponentFixture<MainNavComponent>;
const fakeSidebar = {
sidebarState: of({ sidebar: false }),
};
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [NoopAnimationsModule, AppModule],
providers: [{ provide: AuthService, useClass: AuthMockService },
{ provide: SidebarService, useValue: fakeSidebar }]
})
.compileComponents()
.then(() => {
fixture = TestBed.createComponent(MainNavComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
}));
it('should compile', () => {
expect(component).toBeTruthy();
});
it('should isLoggedIn to true', () => {
//Act
component.login();
// Assert
expect(component.isLoggedIn).toBeTruthy();
});
it('should isLoggedOut to true', () => {
//Act
component.logout();
//Assert
expect(component.isLoggedIn).toBeFalsy();
expect(component.logout).toBeTruthy();
});
it('Should show the sidebar when hasQuestionTree is true', () => {
expect(component.hasQuestionTree).toEqual(false);
});
});
但是这部分:
hasSidebar => (this.hasQuestionTree = hasSidebar));
在代码覆盖率中仍然是红色。
所以我的问题是,如何以正确的方式测试该部分?
谢谢。
好的,我现在是这样的:
const fakeSidebar = {
hasSidebar: () => of({ sidebar: false }),
};
还有这个:
it('Should show the sidebar when hasQuestionTree is true', () => {
expect(component.hasQuestionTree).toEqual(true);
});
但是我得到这个错误:
MainNavComponent Should show the sidebar when hasQuestionTree is true
Expected Object({ sidebar: false }) to equal true.
可能是我遗漏了一些东西,但你在 this.sidebarService
上调用 hasSidebar()
,它随 fakeSidebar
一起提供,但这个对象实际上没有定义 [=14] =] 方法?对我来说,你的模拟对象看起来应该是这样的:
const fakeSidebar = {
hasSidebar: () => of(true),
};
使用 of
运算符也会导致同步可观察对象,因此不需要任何 async
助手,但您可能想使用 observeOn
运算符来更改它并传递 asyncScheduler
来模拟真实世界的行为?!
也更新了这个答案,但我实际上不明白你测试的目的。您只是在测试模拟方法是否 returns 指定的值??