Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/432.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Angular 6-在构造函数中对订阅函数进行单元测试_Javascript_Angular_Unit Testing_Karma Jasmine - Fatal编程技术网

Javascript Angular 6-在构造函数中对订阅函数进行单元测试

Javascript 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'导入{

我一直在尝试对该服务的订阅功能进行单元测试。看看伊斯坦布尔生成的代码覆盖率报告,我可以看到这个代码没有被覆盖

代码 layout.component.ts 这是我的单元测试

布局.组件.规格.ts
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();
    });

});