获取无法读取属性';在';使用Karma Jasmine在Angular中进行单元测试时未定义的
在component.ts文件中,我有一个名为“socketService”的服务,我在其中使用socket,在component中,我有一行获取无法读取属性';在';使用Karma Jasmine在Angular中进行单元测试时未定义的,angular,typescript,unit-testing,socket.io,karma-jasmine,Angular,Typescript,Unit Testing,Socket.io,Karma Jasmine,在component.ts文件中,我有一个名为“socketService”的服务,我在其中使用socket,在component中,我有一行 this.socket = this.socketService.getSocketIOConnector(this.data.product) this.socket.on('connected', (message: string) => { this.connectionMsg = message }) 在我的spec.ts文件中,
this.socket = this.socketService.getSocketIOConnector(this.data.product)
this.socket.on('connected', (message: string) => {
this.connectionMsg = message
})
在我的spec.ts文件中,我有
beforeEach(async(() => {
fixture = TestBed.createComponent(OndemandComponent);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it("should check socket service", inject([SocketioService], (socketioService: SocketioService) => {
socketioService = TestBed.get(SocketioService);
const spy = spyOn(socketioService, "getSocketIOConnector");
expect(spy).toHaveBeenCalled();
}));
it("should create", () => {
expect(component).toBeTruthy();
});
在组件中的this.socket.on附近测试时,无法读取未定义的属性“on”。您没有模拟
getSocketIOConnector
方法的返回值。这就是你出错的原因。此外,您需要调用fixture.detectChanges()代码>在模拟后触发组件的ngOnInit
方法
下面是一个使用angular
v11+的工作示例:
ondemand.component.ts
:
import { Component, OnInit } from '@angular/core';
import { SocketService } from './socket.service';
@Component({})
export class OndemandComponent implements OnInit {
socket: SocketService;
data = {
product: 'real product',
};
connectionMsg: string;
constructor(private socketService: SocketService) {}
ngOnInit() {
this.socket = this.socketService.getSocketIOConnector(this.data.product);
this.socket.on('connected', (message: string) => {
this.connectionMsg = message;
});
}
}
import { ComponentFixture, inject, TestBed } from '@angular/core/testing';
import { OndemandComponent } from './ondemand.component';
import { SocketService } from './socket.service';
fdescribe('65302152', () => {
let fixture: ComponentFixture<OndemandComponent>;
let component: OndemandComponent;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [OndemandComponent],
providers: [SocketService],
}).compileComponents();
fixture = TestBed.createComponent(OndemandComponent);
component = fixture.componentInstance;
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should check socket service', inject(
[SocketService],
(socketioService: SocketService) => {
const connectorSpy = jasmine.createSpyObj('connector', ['on']);
connectorSpy.on.and.callFake((event, listener) => {
listener('fake message');
});
const getSocketIOConnectorSpy = spyOn(
socketioService,
'getSocketIOConnector'
).and.returnValue(connectorSpy);
// trigger ngOnInit of component
fixture.detectChanges();
expect(getSocketIOConnectorSpy).toHaveBeenCalledOnceWith('real product');
expect(connectorSpy.on).toHaveBeenCalledOnceWith(
'connected',
jasmine.any(Function)
);
}
));
});
socket.service.ts
:
import { Component, OnInit } from '@angular/core';
import { SocketService } from './socket.service';
@Component({})
export class OndemandComponent implements OnInit {
socket: SocketService;
data = {
product: 'real product',
};
connectionMsg: string;
constructor(private socketService: SocketService) {}
ngOnInit() {
this.socket = this.socketService.getSocketIOConnector(this.data.product);
this.socket.on('connected', (message: string) => {
this.connectionMsg = message;
});
}
}
import { ComponentFixture, inject, TestBed } from '@angular/core/testing';
import { OndemandComponent } from './ondemand.component';
import { SocketService } from './socket.service';
fdescribe('65302152', () => {
let fixture: ComponentFixture<OndemandComponent>;
let component: OndemandComponent;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [OndemandComponent],
providers: [SocketService],
}).compileComponents();
fixture = TestBed.createComponent(OndemandComponent);
component = fixture.componentInstance;
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should check socket service', inject(
[SocketService],
(socketioService: SocketService) => {
const connectorSpy = jasmine.createSpyObj('connector', ['on']);
connectorSpy.on.and.callFake((event, listener) => {
listener('fake message');
});
const getSocketIOConnectorSpy = spyOn(
socketioService,
'getSocketIOConnector'
).and.returnValue(connectorSpy);
// trigger ngOnInit of component
fixture.detectChanges();
expect(getSocketIOConnectorSpy).toHaveBeenCalledOnceWith('real product');
expect(connectorSpy.on).toHaveBeenCalledOnceWith(
'connected',
jasmine.any(Function)
);
}
));
});
从'@angular/core'导入{Injectable};
@可注射()
出口级SocketService{
getSocketIOConnector(参数){
归还这个;
}
关于(事件,侦听器){}
}
ondemand.component.spec.ts
:
import { Component, OnInit } from '@angular/core';
import { SocketService } from './socket.service';
@Component({})
export class OndemandComponent implements OnInit {
socket: SocketService;
data = {
product: 'real product',
};
connectionMsg: string;
constructor(private socketService: SocketService) {}
ngOnInit() {
this.socket = this.socketService.getSocketIOConnector(this.data.product);
this.socket.on('connected', (message: string) => {
this.connectionMsg = message;
});
}
}
import { ComponentFixture, inject, TestBed } from '@angular/core/testing';
import { OndemandComponent } from './ondemand.component';
import { SocketService } from './socket.service';
fdescribe('65302152', () => {
let fixture: ComponentFixture<OndemandComponent>;
let component: OndemandComponent;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [OndemandComponent],
providers: [SocketService],
}).compileComponents();
fixture = TestBed.createComponent(OndemandComponent);
component = fixture.componentInstance;
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should check socket service', inject(
[SocketService],
(socketioService: SocketService) => {
const connectorSpy = jasmine.createSpyObj('connector', ['on']);
connectorSpy.on.and.callFake((event, listener) => {
listener('fake message');
});
const getSocketIOConnectorSpy = spyOn(
socketioService,
'getSocketIOConnector'
).and.returnValue(connectorSpy);
// trigger ngOnInit of component
fixture.detectChanges();
expect(getSocketIOConnectorSpy).toHaveBeenCalledOnceWith('real product');
expect(connectorSpy.on).toHaveBeenCalledOnceWith(
'connected',
jasmine.any(Function)
);
}
));
});
从'@angular/core/testing'导入{ComponentFixture,inject,TestBed};
从“./ondemand.component”导入{OndemandComponent};
从“./socket.service”导入{SocketService};
fdescribe('65302152',()=>{
let夹具:组件夹具;
let组件:OnDemand组件;
在每个之前(()=>{
TestBed.configureTestingModule({
声明:[OndemandComponent],
提供者:[SocketService],
}).compileComponents();
fixture=TestBed.createComponent(OndemandComponent);
组件=fixture.componentInstance;
});
它('应该创建',()=>{
expect(component.toBeTruthy();
});
它('应该检查套接字服务'),注入(
[SocketService],
(socketioService:SocketService)=>{
const connectorSpy=jasmine.createSpyObj('connector',['on']);
connectorSpy.on.and.callFake((事件,侦听器)=>{
侦听器(“假消息”);
});
const getSocketIOConnectorSpy=spyOn(
socketioService,
“getSocketIOConnector”
).和.返回值(connectorSpy);
//触发元件的非对称性
fixture.detectChanges();
期望(getSocketIOConnectorSpy).与('real product')合并;
期望(connectorSpy.on.)。已与(
“连接”,
jasmine.any(函数)
);
}
));
});
单元测试结果:
嗨!首先,你能把全部代码都写出来吗?是否定义了component.data.product属性?稍后,如果使用inject()方法,则不需要使用TestBed.get()。它们都应该是同一个实例。所以我建议你只用一个。另外,您可以使用TestBed.inject()方法代替socketioService=TestBed.inject(socketioService)代码>希望有帮助。@lorenago谢谢你指出。那是我的错误,我忘了取下床垫。但是我仍然收到相同的错误请告诉我们如何调用测试床。配置测试模块(..)
。您在哪里调用了这个.socket.on
,构造函数或ngOnInit
?@slideshowp2在ngOnInit内部调用它