获取无法读取属性';在';使用Karma Jasmine在Angular中进行单元测试时未定义的

获取无法读取属性';在';使用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文件中,

在component.ts文件中,我有一个名为“socketService”的服务,我在其中使用socket,在component中,我有一行

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内部调用它