当前位置: 首页 > 知识库问答 >
问题:

无法读取处未定义的属性“getAboutInfo”

邢飞鸿
2023-03-14

这是我的代码功能工作正常,但测试用例失败了。请告诉我我在代码中做错了什么?我得到的错误

headless chrome 83 . 0 . 4103(Windows 10 . 0 . 0)about component应创建失败的类型错误:无法读取about component . ngon init(http://localhost:9876/karma _ web pack/src/app/about/about . component . ts:44:28)处的**处的undefined的属性“get about info ”( http://localhost:9876/karma _ web pack/node _ modules/@ angular/core/ivy _ ngcc/fesm 2015/_ tick(http://localhost:9876/karma _ web pack/node _ modules/@ angular/core/ivy _ ngcc/fesm 2015/testing . js:323:1)

import { async, ComponentFixture, TestBed} from '@angular/core/testing';
import { AboutComponent } from './about.component';
import { AboutService } from './about.service';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { Observable, of } from 'rxjs';
import { I18nService } from 'src/utils/i18n.service';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { AppModule } from './../app.module';

describe('AboutComponent', () => {
  let component: AboutComponent;
  let fixture: ComponentFixture<AboutComponent>;
  let dialogSpy: jasmine.Spy;
  let app: any;
  const mockDialogRef = {
    close: jasmine.createSpy('close')
  };
  let service: any;
  const data = '20/04/2019';
  let getAboutInfoSpy: any;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [AboutComponent],
      imports: [HttpClientTestingModule , AppModule],
      providers: [{ provide: AboutService, useValue: service },
        I18nService,
            { provide: MAT_DIALOG_DATA, useValue: {} },
            { provide: MatDialogRef, useValue: mockDialogRef}]
    }).compileComponents();
  }));

  beforeEach(async () => {
    fixture = TestBed.createComponent(AboutComponent);
    component = fixture.componentInstance;
    await fixture.whenStable();
    fixture.detectChanges();
  });

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

  it('infoList should be empty array', () => {
    expect(app['dataList'].length).toBe(0);
  });

  it('when OnInit invoked through service data will return to infoList ', async(() => {
    service = fixture.debugElement.injector.get(AboutService);
    spyOn(service, 'getAboutInfo').and.returnValue(of(data));
    app.ngOnInit();
    expect(app['dataList'].length).toBe(3);
  }));

  it('onCancel should close the dialog', async( () => {
    component.closePopup();
    expect(mockDialogRef.close).toHaveBeenCalled();
  }));

});
import { Component, OnInit, Inject } from '@angular/core';
import { AboutService } from './about.service';
import { Subscription } from 'rxjs';
import { MatDialogRef} from '@angular/material/dialog';
import { I18nService } from 'src/utils/i18n.service';

@Component({
  selector: 'app-about',
  templateUrl: './about.component.html',
  styleUrls: ['./about.component.scss']
})
export class AboutComponent implements OnInit {

  private aboutServiceSubscription: Subscription;
  dataList: any;
  locales: any = {};
  translator: any;
  
  constructor(
    private dialogRef: MatDialogRef<AboutComponent>,
    public aboutService: AboutService,
    private i18Service: I18nService) {}


  ngOnInit() {
    this.translator = this.i18Service.getTranslator();
    this.translator.translateObject.subscribe((item: any) => {
      this.locales = item;
    });
    this.aboutServiceSubscription =  this.aboutService.getAboutInfo().subscribe((data: any) => {
      if (data) {
        data = data.split('/');
        this.dataList = data;
      }
    });
  }


   /**
    * Closes the poup
    * @memberof AboutComponent
    */
  closePopup() {
    this.dialogRef.close();
  }
}
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class AboutService {

  constructor(private http: HttpClient) {

   }

   getAboutInfo() {
    return this.http.get('/assets/aboutInfo.txt', {responseType: 'text'})
  }
}

共有1个答案

水铭晨
2023-03-14

错误消息表明您没有正确模拟AboutService,您将未定义传递给 ,因此通过Injector获得的 。您不能将 spyOn用于 未定义的值。

下面是一个工作示例,删除了不相关的代码:

关于.component.ts

import { Component, OnInit } from '@angular/core';
import { AboutService } from './about.service';
import { Subscription } from 'rxjs';

@Component({
  selector: 'app-about',
})
export class AboutComponent implements OnInit {
  private aboutServiceSubscription: Subscription;
  dataList: any;
  locales: any = {};
  translator: any;

  constructor(public aboutService: AboutService) {}

  ngOnInit() {
    this.aboutServiceSubscription = this.aboutService
      .getAboutInfo()
      .subscribe((data: any) => {
        if (data) {
          data = data.split('/');
          this.dataList = data;
        }
      });
  }
}

about.service.ts

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class AboutService {
  constructor(private http: HttpClient) {}

  getAboutInfo() {
    return this.http.get('/assets/aboutInfo.txt', { responseType: 'text' });
  }
}

about.component.spec.ts

import { HttpClientTestingModule } from '@angular/common/http/testing';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { of } from 'rxjs';
import { AboutComponent } from './about.component';
import { AboutService } from './about.service';

fdescribe('62700708', () => {
  let component: AboutComponent;
  let fixture: ComponentFixture<AboutComponent>;
  let aboutServiceSpy: jasmine.SpyObj<AboutService>;
  const data = '20/04/2019';

  beforeEach(() => {
    aboutServiceSpy = jasmine.createSpyObj('AboutService', ['getAboutInfo']);
    aboutServiceSpy.getAboutInfo.and.returnValue(of(data));

    TestBed.configureTestingModule({
      declarations: [AboutComponent],
      imports: [HttpClientTestingModule],
      providers: [{ provide: AboutService, useValue: aboutServiceSpy }],
    }).compileComponents();
  });

  beforeEach(async () => {
    fixture = TestBed.createComponent(AboutComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

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

  it('when OnInit invoked through service data will return to infoList ', () => {
    expect(aboutServiceSpy.getAboutInfo).toHaveBeenCalledTimes(1);
    expect(component.dataList).toEqual(['20', '04', '2019']);
  });
});

单元测试结果:

 类似资料:
  • 为什么我得到这个错误不能读取未定义的触摸属性? 为什么它不能读取,但它可以读取 当我们使用

  • 问题内容: 我正在制作非常简单的react应用。但是,当我尝试通过onChange事件调用父(实际上是祖父母)组件的方法时,我一直在获取。 这是触发事件的组件/表单(因此,在绑定的父组件上调用方法…是的,因为我通过道具将其从父组件传递下来,所以在方法上使用了.bound(this)。) 这是我如何通过大多数父(祖父母)组件中的props传递该方法的方法。 这是我作为父项(方法所有者和方法调用程序之

  • 我正在测试发送电子邮件与流星js和nodemailer插件: 流星添加捷运:流星NodeEmailer 当页面加载时,我在导航器的控制台上看到错误:无法读取未定义的属性“创建运输”。 那么问题是什么呢? 代码如下: /////////////////////////////////////////// ///////////////

  • 我知道这方面还有很多类似的问题,但没有一个答案是有效的。在我的例子中,我有下面的代码,我正在尝试按分数降序排列记录数组。 最后一个函数是什么给我的问题.如果用户运行以下: var web=[{url:“www.southanpton.ac.uk”,内容:“南安普敦大学提供学位课程和世界一流的研究测试。”,{url:“www.xyz.ac.uk”,内容:“另一种大学考试”},{url:“www”,内

  • 我一直试图让firebase与react一起工作,但出现了此错误 未经处理的拒绝(TypeError):无法读取未定义的fetch D:/Peti/Programming/node/coursewebpage/src/components/coursePage.js:12 9 | const db=firebase.firestore()10 | const myAuthLevel=(fireba

  • 这是我的猫鼬模式: 这是使用Express的Node.js服务器。它具有路由,如果触发该路由,它将使用请求中传递的信息更新用户的购物车。正文: 我打印到终端userCart,正如您在代码中看到的,它返回给我的是: 当服务器执行时,它返回以下错误: 如果我已经在Mongoose中定义了的结构,为什么不定义它?