茉莉单元测试 - TypeError:无法读取未定义的属性(读取' pipe')

发布于 2025-01-23 13:50:59 字数 3287 浏览 2 评论 0原文

typeError:无法在mycomponent.fetchdata上读取未定义的属性(读取'pipe')

我在运行jasmine单位测试时,我会在angular < /代码>。现有的现有不喜欢我的新fetchdata my.component.ts's ngoninit()。我在此规范中的所有六个测试都失败了,同样的错误。有什么想法吗?

my.component.ts

export class MyComponent extends BaseComponent implements OnInit {

  constructor(
    private myService: MyService,
  ) {}

  ngOnInit(): void {

    this.fetchData();

  }

  public fetchData() {
        this.myService.getData()
        .pipe(takeUntil(this.unsubscribe$)).subscribe(  //this.unsubscribe$ gets destroyed in BaseComponent's ngOnDestroy(). Only purpose of BaseComponent is to unsubscribe from observables
          data => {
            if (data) {
              return this.myService.getTypesByCategory(data);
            }
          }
        );
    return;
  }

my.service.ts

export class MyService {

  getData(): Observable<any> {
    return this.httpClient.get('https://myurl.com/myquerystring')
    .pipe(this.showError());
  }

  getTypesByCategory(data) {
                
    for (let region of data.regions) {
          return this.selectType(myArg);
    }
  }

  selectType(myArg): void {
       // do stuff
    
  }
  
}

my.component.spent.spec.ts

import { ComponentFixture, TestBed, fakeAsync, tick, waitForAsync } from '@angular/core/testing';
import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { of } from 'rxjs';
import { Router } from '@angular/router';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { MyService } from 'src/app/my.service';
import { MyComponent } from './mycomponent';

describe('DeviceRegistrationComponent', () => {
  let component: DeviceRegistrationComponent;
  let fixture: ComponentFixture<DeviceRegistrationComponent>;
  let routerSpy: jasmine.SpyObj<Router>;
  let myServiceSpy: jasmine.SpyObj<MyService>;

  beforeEach(
    waitForAsync(() => {
      const myServiceObj = jasmine.createSpyObj('myService', [
        'selectType',
        'getData',
      ]);

      TestBed.configureTestingModule({
        imports: [
          HttpClientTestingModule,
          RouterTestingModule,
          ReactiveFormsModule,
        ],
        declarations: [MyComponent],
        providers: [
          FormBuilder,
          { provide: MyService, useValue: myServiceObj },
        ],
        schemas: [NO_ERRORS_SCHEMA],
      }).compileComponents();


      routerSpy = TestBed.inject(Router) as jasmine.SpyObj<Router>;
      myServiceSpy = TestBed.inject(MyService) as jasmine.SpyObj<MyService>;
      
    }),
  );

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

  it('should be created', () => {
    expect(component).toBeTruthy();

    expect(myServiceSpy.selectType).toHaveBeenCalledWith(true);
  });

  // 5 more tests all fail with the same error

});

TypeError: Cannot read properties of undefined (reading 'pipe') at MyComponent.fetchData

I'm getting the above error when running my Jasmine unit tests in Angular. Existing beforeEach's don't like my new fetchData function in my.component.ts's ngOnInit(). All six of my tests in this spec fail with the same error. Any ideas?

my.component.ts

export class MyComponent extends BaseComponent implements OnInit {

  constructor(
    private myService: MyService,
  ) {}

  ngOnInit(): void {

    this.fetchData();

  }

  public fetchData() {
        this.myService.getData()
        .pipe(takeUntil(this.unsubscribe$)).subscribe(  //this.unsubscribe$ gets destroyed in BaseComponent's ngOnDestroy(). Only purpose of BaseComponent is to unsubscribe from observables
          data => {
            if (data) {
              return this.myService.getTypesByCategory(data);
            }
          }
        );
    return;
  }

my.service.ts

export class MyService {

  getData(): Observable<any> {
    return this.httpClient.get('https://myurl.com/myquerystring')
    .pipe(this.showError());
  }

  getTypesByCategory(data) {
                
    for (let region of data.regions) {
          return this.selectType(myArg);
    }
  }

  selectType(myArg): void {
       // do stuff
    
  }
  
}

my.component.spec.ts

import { ComponentFixture, TestBed, fakeAsync, tick, waitForAsync } from '@angular/core/testing';
import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { of } from 'rxjs';
import { Router } from '@angular/router';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { MyService } from 'src/app/my.service';
import { MyComponent } from './mycomponent';

describe('DeviceRegistrationComponent', () => {
  let component: DeviceRegistrationComponent;
  let fixture: ComponentFixture<DeviceRegistrationComponent>;
  let routerSpy: jasmine.SpyObj<Router>;
  let myServiceSpy: jasmine.SpyObj<MyService>;

  beforeEach(
    waitForAsync(() => {
      const myServiceObj = jasmine.createSpyObj('myService', [
        'selectType',
        'getData',
      ]);

      TestBed.configureTestingModule({
        imports: [
          HttpClientTestingModule,
          RouterTestingModule,
          ReactiveFormsModule,
        ],
        declarations: [MyComponent],
        providers: [
          FormBuilder,
          { provide: MyService, useValue: myServiceObj },
        ],
        schemas: [NO_ERRORS_SCHEMA],
      }).compileComponents();


      routerSpy = TestBed.inject(Router) as jasmine.SpyObj<Router>;
      myServiceSpy = TestBed.inject(MyService) as jasmine.SpyObj<MyService>;
      
    }),
  );

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

  it('should be created', () => {
    expect(component).toBeTruthy();

    expect(myServiceSpy.selectType).toHaveBeenCalledWith(true);
  });

  // 5 more tests all fail with the same error

});

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

哆兒滾 2025-01-30 13:50:59

您的组件期望getData()返回可观察的,然后将其添加.pipe(...)。默认情况下,间谍对象方法返回未定义。您需要模拟函数以返回值,

const myServiceObj = jasmine.createSpyObj('myService', [
        'selectType',
        'getData',
      ]);

也可以模拟返回值

myServiceObj.getData
  .and
  .returnValue(of(true));

Your component expects getData() to return an observable that it then adds a .pipe(...) to. By default the spy object methods return undefined. You need to mock the functions to return values

const myServiceObj = jasmine.createSpyObj('myService', [
        'selectType',
        'getData',
      ]);

You can mock the return value too

myServiceObj.getData
  .and
  .returnValue(of(true));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文