无法在单元测试 NgOnInIt 中读取未定义的属性(读取 'subscribe')

Cannot read properties of undefined (reading 'subscribe') in Unit Test NgOnInIt

我尝试了很多 SO 问题的答案,但在 mt 测试中没有任何效果 this.so 我正在做这样的事情。

const stubStudentService = jasmine.createSpyObj('StudentsCrudService',['getAllStudents','updateStudent']);
const stubWebSocketService = jasmine.createSpyObj('WebsocketService',['getNotified']);

describe('StudentsListComponent', () => {
  let component: StudentsListComponent;
  let fixture: ComponentFixture<StudentsListComponent>;;
  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [StudentsListComponent],
      imports: [],
      providers: [
        { provide: StudentsCrudService, useValue: stubStudentService },
        { provide: WebsocketService, useValue: stubWebSocketService },
        NotificationService,
      ],
    }).compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(StudentsListComponent);
    stubStudentService.getAllStudents.and.returnValue(of(studentPayload));
    stubWebSocketService.getNotified.and.returnValue(of('success'));
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

 it('should create', () => {
  expect(component).toBeTruthy();
 });

在我的组件中,它看起来像这样

  constructor(
    private studentService: StudentsCrudService,
    private notificationService: NotificationService,
    private webSocketNotifier: WebsocketService
  ) {}

  ngOnInit(): void {
    this.studentSubscription();
    this.webSocketSubscription();
  }

  studentSubscription() {
    this.studentQueryRef =  this.studentService
    .getAllStudents()
    this.initSubscription.add(
      this.studentQueryRef
        .valueChanges.subscribe((response) => {
          this.paginatedStudents = {...response.data.paginateStudents}
        })
    );
  }

当我 运行 测试时我得到 Cannot read properties of undefined (reading 'subscribe') at StudentsListComponent.studentSubscription。我尝试了很多东西,但没有任何效果。

第一个fixture.detectChanges是调用ngOnInit的时候

你已经正确地嘲笑了 studentService 但你没有错误地嘲笑 getAllStudents 的 return。

试试这个(在评论后面加上!!):

const stubStudentService = jasmine.createSpyObj('StudentsCrudService',['getAllStudents','updateStudent']);
const stubWebSocketService = jasmine.createSpyObj('WebsocketService',['getNotified']);

describe('StudentsListComponent', () => {
  let component: StudentsListComponent;
  let fixture: ComponentFixture<StudentsListComponent>;
  // !! make the following changes
  let stubStudentService: jasmine.SpyObj<StudentCrudService>;
  let stubWebSocketService: jasmine.SpyObj<WebsocketService>;
  
  beforeEach(async () => {
    // !! assign the spies in a beforeEach so they are fresh for every test
    stubStudentService = jasmine.createSpyObj('StudentsCrudService', 
      ['getAllStudents','updateStudent']);
    stubWebSocketService = jasmine.createSpyObj('WebsocketService', 
    ['getNotified']);

    await TestBed.configureTestingModule({
      declarations: [StudentsListComponent],
      imports: [],
      providers: [
        { provide: StudentsCrudService, useValue: stubStudentService },
        { provide: WebsocketService, useValue: stubWebSocketService },
        NotificationService,
      ],
    }).compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(StudentsListComponent);
    // !! change below to return object of valueChanges
    stubStudentService.getAllStudents.and.returnValue({ valueChanges: of(studentPayload) });
    stubWebSocketService.getNotified.and.returnValue(of('success'));
    component = fixture.componentInstance;
    // !! the below fixture.detectChanges will call ngOnInit
    fixture.detectChanges();
  });

 it('should create', () => {
  expect(component).toBeTruthy();
 });

以上内容有望解决您的问题。