Javascript Angular 6-在构造函数中对订阅函数进行单元测试
我一直在尝试对该服务的订阅功能进行单元测试。看看伊斯坦布尔生成的代码覆盖率报告,我可以看到这个代码没有被覆盖 代码 layout.component.ts 这是我的单元测试 布局.组件.规格.tsJavascript Angular 6-在构造函数中对订阅函数进行单元测试,javascript,angular,unit-testing,karma-jasmine,Javascript,Angular,Unit Testing,Karma Jasmine,我一直在尝试对该服务的订阅功能进行单元测试。看看伊斯坦布尔生成的代码覆盖率报告,我可以看到这个代码没有被覆盖 代码 layout.component.ts 这是我的单元测试 布局.组件.规格.ts import{CUSTOM_ELEMENTS_SCHEMA,NO_ERRORS_SCHEMA}来自'@angular/core'; 从'@angular/core/testing'导入{async,ComponentFixture,fakeAsync,TestBed,tick}; 从'rxjs'导入{
import{CUSTOM_ELEMENTS_SCHEMA,NO_ERRORS_SCHEMA}来自'@angular/core';
从'@angular/core/testing'导入{async,ComponentFixture,fakeAsync,TestBed,tick};
从'rxjs'导入{of};
从“./layout.component”导入{LayoutComponent};
从“./layout.service”导入{LayoutService};
描述('LayoutComponent',()=>{
let组件:布局组件;
let夹具:组件夹具;
让服务;
beforeach(异步(()=>{
服务=新布局服务();
mockLayoutService=jasmine.createSpyObj('LayoutService',['messagePublished$');
TestBed.configureTestingModule({
声明:[
布局组件,
],
供应商:[
排班服务
],
模式:[
无错误模式、自定义元素模式
]
})
.compileComponents();
}));
在每个之前(()=>{
fixture=TestBed.createComponent(LayoutComponent);
组件=fixture.componentInstance;
fixture.detectChanges();
component.message='Garbage';
});
它('should call messagePublished',()=>{
spyOn(service.messagePublished$,'subscribe');
createComponent(LayoutComponent);
expect(service.messagePublished$.subscribe).tohavebeencall();
});
描述('setMessage',()=>{
它('应该设置消息',fakeAsync(()=>{
setMessage('Message');
expect(component.message).toBe('message');
勾号(7000);
expect(component.message).toBeNull();
}));
});
});
因此,代码似乎永远不会超过“service.messagePublished$.subscribe”部分。这是你的电话号码
我得到的错误是“Expected spy subscribe to have called”,我猜这是当代码块未被覆盖时出现的错误。我建议您将订阅从构造函数移动到
ngOnInit
。Angular创建了几个生命周期挂钩,在创建组件(Ngonit)时调用这些挂钩,在数据更改或销毁时调用其他挂钩-请参阅
这样,您可以通过调用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();
});
});
import{CUSTOM_ELEMENTS_SCHEMA,NO_ERRORS_SCHEMA}来自'@angular/core';
从'@angular/core/testing'导入{async,ComponentFixture,fakeAsync,TestBed,tick};
从'rxjs'导入{of};
从“./layout.component”导入{LayoutComponent};
从“./layout.service”导入{LayoutService};
描述('LayoutComponent',()=>{
let组件:布局组件;
let夹具:组件夹具;
让服务间谍:jasmine.SpyObj;;
beforeach(异步(()=>{
const spy=spyOn(service.messagePublished$,'subscribe')
TestBed.configureTestingModule({
声明:[
布局组件,
],
供应商:[
{provide:LayoutService,useValue:spy}
],
模式:[
无错误模式、自定义元素模式
]
})
.compileComponents();
serviceSpy=TestBed.get(ValueService);
}));
在每个之前(()=>{
fixture=TestBed.createComponent(LayoutComponent);
组件=fixture.componentInstance;
fixture.detectChanges();
component.message='Garbage';
});
它('should call messagePublished',()=>{
createComponent(LayoutComponent);
expect(service.messagePublished$.subscribe).tohavebeencall();
});
});
这是个好主意,但我现在只负责单元测试。所以我不能真正改变代码。我必须找到一种方法来访问构造函数中的代码。更新了用于测试构造函数测试的代码。希望它能让您了解如何检查代码是否已运行。这是因为您在以下行中使用模拟替换了LayoutService:Provider:LayoutService,useValue:mockLayoutService
和mockLayoutService没有messagePublished$属性。mockLayoutService需要是具有属性messagePublished$的对象,该属性具有subscribe属性。代码已更新。我希望它能给你一个更清晰的画面;with service=TestBed.get(LayoutService);在configureTestingModule()方法之后
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();
}));
});
});
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();
});
});