我一直在尝试对该服务的订阅功能进行单元测试。查看 istanbul 生成的代码覆盖率报告,我可以看到这段代码没有被覆盖。
代码
layout.component.ts
import {Component, HostListener, Input} from '@angular/core';
import { LayoutService } from './layout.service';
import { some } from 'lodash';
@Component({
selector: 'cgm-layout',
templateUrl: './layout.component.html',
styleUrls: ['./layout.component.scss'],
providers: [LayoutService]
})
class LayoutComponent {
message: any;
constructor(
private service: LayoutService
) {
service.messagePublished$.subscribe(
message => {
this.setMessage(message);
}
);
}
setMessage(message): void {
this.message = message;
setTimeout(() => {
this.message = null;
}, 7000);
}
}
export {
LayoutComponent
};
这是我的单元测试
layout.component.spec.ts
import { CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA } from '@angular/core';
import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
import { of } from 'rxjs';
import { LayoutComponent } from './layout.component';
import { LayoutService } from './layout.service';
describe('LayoutComponent', () => {
let component: LayoutComponent;
let fixture: ComponentFixture<LayoutComponent>;
let service;
beforeEach(async(() => {
service = new LayoutService();
mockLayoutService = jasmine.createSpyObj('LayoutService', ['messagePublished$']);
TestBed.configureTestingModule({
declarations: [
LayoutComponent,
],
providers: [
LayoutService
],
schemas: [
NO_ERRORS_SCHEMA, CUSTOM_ELEMENTS_SCHEMA
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(LayoutComponent);
component = fixture.componentInstance;
fixture.detectChanges();
component.message = 'Garbage';
});
it('should call messagePublished', () => {
spyOn(service.messagePublished$, 'subscribe');
TestBed.createComponent(LayoutComponent);
expect(service.messagePublished$.subscribe).toHaveBeenCalled();
});
describe('setMessage', () => {
it('should set the Message', fakeAsync(() => {
component.setMessage('Message');
expect(component.message).toBe('Message');
tick(7000);
expect(component.message).toBeNull();
}));
});
});
所以代码似乎永远不会越过“service.messagePublished$.subscribe”部分。这是 code coverage report .
我得到的错误是“Expected spy subscribe to have been called”,我猜这是你在没有覆盖该代码块时得到的错误。
最佳答案
我建议您将订阅从构造函数移至 ngOnInit
。 Angular 创建了几个生命周期 Hook ,它们在创建组件 (ngOnInit) 时调用,在数据更改或销毁时调用 - 参见 Angular lifecycle hooks .
这样您就可以通过调用 ngOnInit()
方法来测试您的代码。
如果您无法更改代码,您可以尝试创建一个组件实例并检查是否像下面的伪代码那样调用了您的方法:
import { CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA } from '@angular/core';
import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
import { of } from 'rxjs';
import { LayoutComponent } from './layout.component';
import { LayoutService } from './layout.service';
describe('LayoutComponent', () => {
let component: LayoutComponent;
let fixture: ComponentFixture<LayoutComponent>;
let serviceSpy: jasmine.SpyObj<LayoutService>;;
beforeEach(async(() => {
const spy = spyOn(service.messagePublished$, 'subscribe')
TestBed.configureTestingModule({
declarations: [
LayoutComponent,
],
providers: [
{ provide: LayoutService, useValue: spy }
],
schemas: [
NO_ERRORS_SCHEMA, CUSTOM_ELEMENTS_SCHEMA
]
})
.compileComponents();
serviceSpy = TestBed.get(ValueService);
}));
beforeEach(() => {
fixture = TestBed.createComponent(LayoutComponent);
component = fixture.componentInstance;
fixture.detectChanges();
component.message = 'Garbage';
});
it('should call messagePublished', () => {
TestBed.createComponent(LayoutComponent);
expect(service.messagePublished$.subscribe).toHaveBeenCalled();
});
});
关于javascript - Angular 6 - 单元测试构造函数中的订阅函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53260326/