Получение не может прочитать свойство ‘on’ неопределенного в модульном тестировании в Angular с использованием Karma Jasmine

#angular #typescript #unit-testing #socket.io #karma-jasmine

#angular #typescript #модульное тестирование #socket.io #karma-jasmine

Вопрос:

В моем файле component.ts у меня есть служба с именем ‘socketService’, где я использую сокет, а в компоненте у меня есть строка

 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();
});
 

Это выдает мне ошибку типа: невозможно прочитать свойство ‘on’ из undefined при тестировании рядом с этим.socket.включено в компоненте.

Комментарии:

1. Привет! Прежде всего, можете ли вы поместить весь код целиком? Вы определили свойство component.data.product? Позже, если вы используете метод inject (), вам не нужно использовать TestBed.get() . Оба они должны быть одним и тем же экземпляром. Поэтому я рекомендую вам использовать только один. Кроме того, вы можете использовать метод TestBed.inject() вместо socketioService = TestBed.inject(SocketioService); этого, надеюсь, это поможет.

2. @lorenago Спасибо, что указали на это. Это была моя ошибка, я забыл удалить тетрадь. Но я все еще получаю ту же ошибку

3. Пожалуйста, покажите нам, как вы вызываете TestBed.configureTestingModule(..) .

4. Куда вы звонили this.socket.on , constructor или ngOnInit ?

5. @slideshowp2 вызывает его внутри ngOnInit

Ответ №1:

Вы не издевались над возвращаемым значением 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;
    });
  }
}
 

socket.service.ts :

 import { Injectable } from '@angular/core';

@Injectable()
export class SocketService {
  getSocketIOConnector(params) {
    return this;
  }
  on(event, listener) {}
}
 

ondemand.component.spec.ts :

 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)
      );
    }
  ));
});
 

результат модульного теста:

введите описание изображения здесь